Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 183 additions & 0 deletions syntheticsclientv2/common_models.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,79 @@
package syntheticsclientv2

import (
"encoding/json"
"time"
)

// Common and shared struct models used for more complex requests
type NullableString struct {
Value *string
}

func NewNullableString(value string) *NullableString {
return &NullableString{Value: &value}
}

func NewNullString() *NullableString {
return &NullableString{}
}

func (n NullableString) MarshalJSON() ([]byte, error) {
if n.Value == nil {
return []byte("null"), nil
}

return json.Marshal(*n.Value)
}

func (n *NullableString) UnmarshalJSON(data []byte) error {
if string(data) == "null" {
n.Value = nil
return nil
}

var value string
if err := json.Unmarshal(data, &value); err != nil {
return err
}
n.Value = &value
return nil
}

type NullableInt struct {
Value *int
}

func NewNullableInt(value int) *NullableInt {
return &NullableInt{Value: &value}
}

func NewNullInt() *NullableInt {
return &NullableInt{}
}

func (n NullableInt) MarshalJSON() ([]byte, error) {
if n.Value == nil {
return []byte("null"), nil
}

return json.Marshal(*n.Value)
}

func (n *NullableInt) UnmarshalJSON(data []byte) error {
if string(data) == "null" {
n.Value = nil
return nil
}

var value int
if err := json.Unmarshal(data, &value); err != nil {
return err
}
n.Value = &value
return nil
}

type Networkconnection struct {
Description string `json:"description,omitempty"`
Downloadbandwidth int `json:"downloadBandwidth,omitempty"`
Expand Down Expand Up @@ -314,6 +383,120 @@ type ChecksV2Response struct {
Totalcount int `json:"totalCount"`
}

type CaCertificate struct {
ID int `json:"id,omitempty"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
Content string `json:"content,omitempty"`
FileExtension string `json:"fileExtension,omitempty"`
Filename string `json:"filename,omitempty"`
ExpiresAt time.Time `json:"expiresAt,omitempty"`
CreatedAt time.Time `json:"createdAt,omitempty"`
CreatedBy string `json:"createdBy,omitempty"`
UpdatedAt time.Time `json:"updatedAt,omitempty"`
UpdatedBy string `json:"updatedBy,omitempty"`
}

type CaCertificateInput struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Content string `json:"content,omitempty"`
FileExtension string `json:"fileExtension,omitempty"`
Filename string `json:"filename,omitempty"`
}

type CaCertificateUpdateInput struct {
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
Content *string `json:"content,omitempty"`
FileExtension *string `json:"fileExtension,omitempty"`
Filename *string `json:"filename,omitempty"`
}

type CaCertificateV2Input struct {
CaCert CaCertificateInput `json:"cacert"`
}

type CaCertificateV2UpdateInput struct {
CaCert CaCertificateUpdateInput `json:"cacert"`
}

type CaCertificateV2Response struct {
CaCert CaCertificate `json:"cacert"`
}

type CaCertificatesV2Response struct {
CaCerts []CaCertificate `json:"cacerts"`
}

type SslCheckV2Response struct {
Test struct {
ID int `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Active bool `json:"active"`
Frequency int `json:"frequency,omitempty"`
SchedulingStrategy string `json:"schedulingStrategy,omitempty"`
CreatedAt time.Time `json:"createdAt,omitempty"`
UpdatedAt time.Time `json:"updatedAt,omitempty"`
LocationIds []string `json:"locationIds,omitempty"`
Type string `json:"type,omitempty"`
Host string `json:"host,omitempty"`
Port int `json:"port,omitempty"`
ServerName *string `json:"serverName,omitempty"`
AllowSelfSigned bool `json:"allowSelfSigned"`
AllowUntrustedRoot bool `json:"allowUntrustedRoot"`
CaCertificateID *int `json:"caCertificateId"`
Validations []Validations `json:"validations"`
Customproperties []CustomProperties `json:"customProperties"`
Lastrunstatus string `json:"lastRunStatus"`
Lastrunat time.Time `json:"lastRunAt"`
LastRunCoreMetricsPublishedAt time.Time `json:"lastRunCoreMetricsPublishedAt"`
LastRunLocationId string `json:"lastRunLocationId"`
LastRunId int `json:"lastRunId"`
Automaticretries int `json:"automaticRetries"`
Createdby string `json:"createdBy"`
Updatedby string `json:"updatedBy"`
} `json:"test"`
}

type SslCheckV2Input struct {
Test struct {
Name string `json:"name"`
LocationIds []string `json:"locationIds"`
Frequency int `json:"frequency"`
SchedulingStrategy string `json:"schedulingStrategy"`
Active bool `json:"active"`
Customproperties []CustomProperties `json:"customProperties"`
Automaticretries int `json:"automaticRetries"`
Host string `json:"host"`
Port int `json:"port"`
ServerName *string `json:"serverName"`
AllowSelfSigned bool `json:"allowSelfSigned"`
AllowUntrustedRoot bool `json:"allowUntrustedRoot"`
CaCertificateID *int `json:"caCertificateId"`
Validations []Validations `json:"validations"`
} `json:"test"`
}

type SslCheckV2UpdateInput struct {
Test struct {
Name *string `json:"name,omitempty"`
LocationIds *[]string `json:"locationIds,omitempty"`
Frequency *int `json:"frequency,omitempty"`
SchedulingStrategy *string `json:"schedulingStrategy,omitempty"`
Active *bool `json:"active,omitempty"`
Customproperties *[]CustomProperties `json:"customProperties,omitempty"`
Automaticretries *int `json:"automaticRetries,omitempty"`
Host *string `json:"host,omitempty"`
Port *int `json:"port,omitempty"`
ServerName *NullableString `json:"serverName,omitempty"`
AllowSelfSigned *bool `json:"allowSelfSigned,omitempty"`
AllowUntrustedRoot *bool `json:"allowUntrustedRoot,omitempty"`
CaCertificateID *NullableInt `json:"caCertificateId,omitempty"`
Validations *[]Validations `json:"validations,omitempty"`
} `json:"test"`
}

type PortCheckV2Response struct {
Test struct {
ID int `json:"id"`
Expand Down
50 changes: 50 additions & 0 deletions syntheticsclientv2/create_cacertificatev2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2026 Splunk, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package syntheticsclientv2

import (
"bytes"
"encoding/json"
)

func parseCreateCaCertificateV2Response(response string) (*CaCertificateV2Response, error) {
var createCaCertificateV2 CaCertificateV2Response
JSONResponse := []byte(response)
err := json.Unmarshal(JSONResponse, &createCaCertificateV2)
if err != nil {
return nil, err
}

return &createCaCertificateV2, err
}

func (c Client) CreateCaCertificateV2(CaCertificateV2Details *CaCertificateV2Input) (*CaCertificateV2Response, *RequestDetails, error) {
body, err := json.Marshal(CaCertificateV2Details)
if err != nil {
return nil, nil, err
}

details, err := c.makePublicAPICall("POST", "/cacerts", bytes.NewBuffer(body), nil)
if err != nil {
return nil, details, err
}

newCaCertificateV2, err := parseCreateCaCertificateV2Response(details.ResponseBody)
if err != nil {
return newCaCertificateV2, details, err
}

return newCaCertificateV2, details, nil
}
124 changes: 124 additions & 0 deletions syntheticsclientv2/create_cacertificatev2_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
//go:build unit_tests
// +build unit_tests

// Copyright 2026 Splunk, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package syntheticsclientv2

import (
"encoding/json"
"io"
"net/http"
"reflect"
"testing"
)

var (
createCaCertificateV2Body = `{"cacert":{"name":"foo","description":"My CA certificate","content":"Q2VydGlmaWNhdGU=","fileExtension":"pem","filename":"ca_cert_file"}}`
createCaCertificateV2ResponseBody = `{"cacert":{"id":1,"name":"foo","description":"My CA certificate","content":"<REDACTED>","fileExtension":"pem","filename":"ca_cert_file","expiresAt":"2026-09-14T14:35:37.801Z","createdAt":"2022-09-14T14:35:37.801Z","createdBy":"abcdefgh1234","updatedAt":"2022-09-14T14:35:38.099Z","updatedBy":"abcdefgh1234"}}`
inputCaCertificateV2Data = CaCertificateV2Input{}
outputCaCertificateV2Data = CaCertificateV2Response{}
)

func TestCreateCaCertificateV2(t *testing.T) {
setup()
defer teardown()

testMux.HandleFunc("/cacerts", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")

requestBody, err := io.ReadAll(r.Body)
if err != nil {
t.Fatal(err)
}

var requestEnvelope map[string]json.RawMessage
err = json.Unmarshal(requestBody, &requestEnvelope)
if err != nil {
t.Fatal(err)
}
if len(requestEnvelope) != 1 {
t.Fatalf("request body envelope keys \n\n%#v want only cacert", requestEnvelope)
}
rawCaCert, ok := requestEnvelope["cacert"]
if !ok {
t.Fatal("request body missing cacert envelope")
}

var requestCaCertFields map[string]json.RawMessage
err = json.Unmarshal(rawCaCert, &requestCaCertFields)
if err != nil {
t.Fatal(err)
}
writableFields := []string{"name", "description", "content", "fileExtension", "filename"}
if len(requestCaCertFields) != len(writableFields) {
t.Errorf("request body cacert field count \n\n%#v want \n\n%#v", len(requestCaCertFields), len(writableFields))
}
for _, field := range writableFields {
if _, ok := requestCaCertFields[field]; !ok {
t.Errorf("request body missing cacert.%s", field)
}
}
for _, field := range []string{"id", "expiresAt", "createdAt", "createdBy", "updatedAt", "updatedBy"} {
if _, ok := requestCaCertFields[field]; ok {
t.Errorf("request body includes response-only cacert.%s", field)
}
}

requestCaCertificateV2Data := CaCertificateV2Input{}
err = json.Unmarshal(requestBody, &requestCaCertificateV2Data)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(requestCaCertificateV2Data.CaCert.Name, inputCaCertificateV2Data.CaCert.Name) {
t.Errorf("request body name \n\n%#v want \n\n%#v", requestCaCertificateV2Data.CaCert.Name, inputCaCertificateV2Data.CaCert.Name)
}
if !reflect.DeepEqual(requestCaCertificateV2Data.CaCert.Description, inputCaCertificateV2Data.CaCert.Description) {
t.Errorf("request body description \n\n%#v want \n\n%#v", requestCaCertificateV2Data.CaCert.Description, inputCaCertificateV2Data.CaCert.Description)
}
if !reflect.DeepEqual(requestCaCertificateV2Data.CaCert.Content, inputCaCertificateV2Data.CaCert.Content) {
t.Errorf("request body content \n\n%#v want \n\n%#v", requestCaCertificateV2Data.CaCert.Content, inputCaCertificateV2Data.CaCert.Content)
}
if !reflect.DeepEqual(requestCaCertificateV2Data.CaCert.FileExtension, inputCaCertificateV2Data.CaCert.FileExtension) {
t.Errorf("request body file extension \n\n%#v want \n\n%#v", requestCaCertificateV2Data.CaCert.FileExtension, inputCaCertificateV2Data.CaCert.FileExtension)
}
if !reflect.DeepEqual(requestCaCertificateV2Data.CaCert.Filename, inputCaCertificateV2Data.CaCert.Filename) {
t.Errorf("request body filename \n\n%#v want \n\n%#v", requestCaCertificateV2Data.CaCert.Filename, inputCaCertificateV2Data.CaCert.Filename)
}

_, err = w.Write([]byte(createCaCertificateV2ResponseBody))
if err != nil {
t.Fatal(err)
}
})

err := json.Unmarshal([]byte(createCaCertificateV2Body), &inputCaCertificateV2Data)
if err != nil {
t.Fatal(err)
}
err = json.Unmarshal([]byte(createCaCertificateV2ResponseBody), &outputCaCertificateV2Data)
if err != nil {
t.Fatal(err)
}

resp, _, err := testClient.CreateCaCertificateV2(&inputCaCertificateV2Data)
if err != nil {
t.Fatal(err)
}

if !reflect.DeepEqual(resp.CaCert, outputCaCertificateV2Data.CaCert) {
t.Errorf("returned \n\n%#v want \n\n%#v", resp.CaCert, outputCaCertificateV2Data.CaCert)
}
}
Loading
Loading