44 "context"
55 "fmt"
66
7- "github.com/elastic/terraform-provider-elasticstack/generated/kbapi"
8- "github.com/hashicorp/terraform-plugin-framework/diag"
7+ "github.com/elastic/terraform-provider-elasticstack/internal/clients"
98 "github.com/hashicorp/terraform-plugin-framework/resource"
9+ "github.com/hashicorp/terraform-plugin-framework/types"
1010)
1111
1212func (r * securityDetectionRuleResource ) Create (ctx context.Context , req resource.CreateRequest , resp * resource.CreateResponse ) {
@@ -28,7 +28,7 @@ func (r *securityDetectionRuleResource) Create(ctx context.Context, req resource
2828 }
2929
3030 // Build the create request
31- createProps , diags := r . buildCreateProps (ctx , data )
31+ createProps , diags := data . toCreateProps (ctx )
3232 resp .Diagnostics .Append (diags ... )
3333 if resp .Diagnostics .HasError () {
3434 return
@@ -52,187 +52,32 @@ func (r *securityDetectionRuleResource) Create(ctx context.Context, req resource
5252 return
5353 }
5454
55- // Parse the response
55+ // Parse the response to get the ID, then use Read logic for consistency
5656 ruleResponse , diags := r .parseRuleResponse (ctx , response .JSON200 )
5757 resp .Diagnostics .Append (diags ... )
5858 if resp .Diagnostics .HasError () {
5959 return
6060 }
6161
62- // Update the data with response values
63- diags = r .updateDataFromRule (ctx , & data , ruleResponse )
64- resp .Diagnostics .Append (diags ... )
65- if resp .Diagnostics .HasError () {
66- return
67- }
68-
69- resp .Diagnostics .Append (resp .State .Set (ctx , & data )... )
70- }
71-
72- func (r * securityDetectionRuleResource ) buildCreateProps (ctx context.Context , data SecurityDetectionRuleData ) (kbapi.SecurityDetectionsAPIRuleCreateProps , diag.Diagnostics ) {
73- var diags diag.Diagnostics
74- var createProps kbapi.SecurityDetectionsAPIRuleCreateProps
75-
76- queryRuleQuery := kbapi .SecurityDetectionsAPIRuleQuery (data .Query .ValueString ())
77- // Convert data to QueryRuleCreateProps since we're only supporting query rules initially
78- queryRule := kbapi.SecurityDetectionsAPIQueryRuleCreateProps {
79- Name : kbapi .SecurityDetectionsAPIRuleName (data .Name .ValueString ()),
80- Description : kbapi .SecurityDetectionsAPIRuleDescription (data .Description .ValueString ()),
81- Type : kbapi .SecurityDetectionsAPIQueryRuleCreatePropsType ("query" ),
82- Query : & queryRuleQuery ,
83- RiskScore : kbapi .SecurityDetectionsAPIRiskScore (data .RiskScore .ValueInt64 ()),
84- Severity : kbapi .SecurityDetectionsAPISeverity (data .Severity .ValueString ()),
85- }
86-
87- // Set optional rule_id if provided
88- if ! data .RuleId .IsNull () && ! data .RuleId .IsUnknown () {
89- ruleId := kbapi .SecurityDetectionsAPIRuleSignatureId (data .RuleId .ValueString ())
90- queryRule .RuleId = & ruleId
91- }
92-
93- // Set enabled status
94- if ! data .Enabled .IsNull () {
95- enabled := kbapi .SecurityDetectionsAPIIsRuleEnabled (data .Enabled .ValueBool ())
96- queryRule .Enabled = & enabled
97- }
98-
99- // Set query language
100- if ! data .Language .IsNull () {
101- var language kbapi.SecurityDetectionsAPIKqlQueryLanguage
102- switch data .Language .ValueString () {
103- case "kuery" :
104- language = "kuery"
105- case "lucene" :
106- language = "lucene"
107- default :
108- language = "kuery"
109- }
110- queryRule .Language = & language
111- }
112-
113- // Set time range
114- if ! data .From .IsNull () {
115- from := kbapi .SecurityDetectionsAPIRuleIntervalFrom (data .From .ValueString ())
116- queryRule .From = & from
117- }
118-
119- if ! data .To .IsNull () {
120- to := kbapi .SecurityDetectionsAPIRuleIntervalTo (data .To .ValueString ())
121- queryRule .To = & to
122- }
123-
124- // Set interval
125- if ! data .Interval .IsNull () {
126- interval := kbapi .SecurityDetectionsAPIRuleInterval (data .Interval .ValueString ())
127- queryRule .Interval = & interval
128- }
129-
130- // Set index patterns
131- if ! data .Index .IsNull () && ! data .Index .IsUnknown () {
132- var indexList []string
133- diags .Append (data .Index .ElementsAs (ctx , & indexList , false )... )
134- if ! diags .HasError () && len (indexList ) > 0 {
135- indexPatterns := make (kbapi.SecurityDetectionsAPIIndexPatternArray , len (indexList ))
136- //nolint:staticcheck // Type conversion required, can't use copy()
137- for i , idx := range indexList {
138- indexPatterns [i ] = idx
139- }
140- queryRule .Index = & indexPatterns
141- }
142- }
143-
144- // Set author
145- if ! data .Author .IsNull () && ! data .Author .IsUnknown () {
146- var authorList []string
147- diags .Append (data .Author .ElementsAs (ctx , & authorList , false )... )
148- if ! diags .HasError () && len (authorList ) > 0 {
149- authorArray := make (kbapi.SecurityDetectionsAPIRuleAuthorArray , len (authorList ))
150- //nolint:staticcheck // Type conversion required, can't use copy()
151- for i , author := range authorList {
152- authorArray [i ] = author
153- }
154- queryRule .Author = & authorArray
155- }
156- }
157-
158- // Set tags
159- if ! data .Tags .IsNull () && ! data .Tags .IsUnknown () {
160- var tagsList []string
161- diags .Append (data .Tags .ElementsAs (ctx , & tagsList , false )... )
162- if ! diags .HasError () && len (tagsList ) > 0 {
163- tagsArray := make (kbapi.SecurityDetectionsAPIRuleTagArray , len (tagsList ))
164- //nolint:staticcheck // Type conversion required, can't use copy()
165- for i , tag := range tagsList {
166- tagsArray [i ] = tag
167- }
168- queryRule .Tags = & tagsArray
169- }
170- }
171-
172- // Set false positives
173- if ! data .FalsePositives .IsNull () && ! data .FalsePositives .IsUnknown () {
174- var fpList []string
175- diags .Append (data .FalsePositives .ElementsAs (ctx , & fpList , false )... )
176- if ! diags .HasError () && len (fpList ) > 0 {
177- fpArray := make (kbapi.SecurityDetectionsAPIRuleFalsePositiveArray , len (fpList ))
178- //nolint:staticcheck // Type conversion required, can't use copy()
179- for i , fp := range fpList {
180- fpArray [i ] = fp
181- }
182- queryRule .FalsePositives = & fpArray
183- }
184- }
185-
186- // Set references
187- if ! data .References .IsNull () && ! data .References .IsUnknown () {
188- var refList []string
189- diags .Append (data .References .ElementsAs (ctx , & refList , false )... )
190- if ! diags .HasError () && len (refList ) > 0 {
191- refArray := make (kbapi.SecurityDetectionsAPIRuleReferenceArray , len (refList ))
192- //nolint:staticcheck // Type conversion required, can't use copy()
193- for i , ref := range refList {
194- refArray [i ] = ref
195- }
196- queryRule .References = & refArray
197- }
198- }
199-
200- // Set optional string fields
201- if ! data .License .IsNull () {
202- license := kbapi .SecurityDetectionsAPIRuleLicense (data .License .ValueString ())
203- queryRule .License = & license
62+ // Set the ID based on the created rule
63+ compId := clients.CompositeId {
64+ ClusterId : data .SpaceId .ValueString (),
65+ ResourceId : ruleResponse .Id .String (),
20466 }
67+ data .Id = types .StringValue (compId .String ())
20568
206- if ! data . Note . IsNull () {
207- note := kbapi . SecurityDetectionsAPIInvestigationGuide ( data . Note . ValueString ())
208- queryRule . Note = & note
69+ // Use Read logic to populate the state with fresh data from the API
70+ readReq := resource. ReadRequest {
71+ State : resp . State ,
20972 }
73+ var readResp resource.ReadResponse
74+ readReq .State .Set (ctx , & data )
75+ r .Read (ctx , readReq , & readResp )
21076
211- if ! data .Setup .IsNull () {
212- setup := kbapi .SecurityDetectionsAPISetupGuide (data .Setup .ValueString ())
213- queryRule .Setup = & setup
214- }
215-
216- // Set max signals
217- if ! data .MaxSignals .IsNull () {
218- maxSignals := kbapi .SecurityDetectionsAPIMaxSignals (data .MaxSignals .ValueInt64 ())
219- queryRule .MaxSignals = & maxSignals
220- }
221-
222- // Set version
223- if ! data .Version .IsNull () {
224- version := kbapi .SecurityDetectionsAPIRuleVersion (data .Version .ValueInt64 ())
225- queryRule .Version = & version
226- }
227-
228- // Convert to union type
229- err := createProps .FromSecurityDetectionsAPIQueryRuleCreateProps (queryRule )
230- if err != nil {
231- diags .AddError (
232- "Error building create properties" ,
233- "Could not convert rule properties: " + err .Error (),
234- )
77+ resp .Diagnostics .Append (readResp .Diagnostics ... )
78+ if resp .Diagnostics .HasError () {
79+ return
23580 }
23681
237- return createProps , diags
82+ resp . State = readResp . State
23883}
0 commit comments