Skip to content

Commit c7b8728

Browse files
feat(api): add health check endpoint for proxies
1 parent ccb1425 commit c7b8728

File tree

4 files changed

+329
-4
lines changed

4 files changed

+329
-4
lines changed

.stats.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 89
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-2cf104c4b88159c6a50713b019188f83983748b9cacec598089cf9068dc5b1cd.yml
3-
openapi_spec_hash: 84ea30ae65ad7ebcc04d2f3907d1e73b
4-
config_hash: 179f33af31ece83563163d5b3d751d13
1+
configured_endpoints: 90
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-20fac779e9e13dc9421e467be31dbf274c39072ba0c01528ba451b48698d43c1.yml
3+
openapi_spec_hash: c3fc5784297ccc8f729326b62000d1f0
4+
config_hash: e47e015528251ee83e30367dbbb51044

api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,15 @@ Response Types:
205205
- <a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#ProxyNewResponse">ProxyNewResponse</a>
206206
- <a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#ProxyGetResponse">ProxyGetResponse</a>
207207
- <a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#ProxyListResponse">ProxyListResponse</a>
208+
- <a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#ProxyCheckResponse">ProxyCheckResponse</a>
208209

209210
Methods:
210211

211212
- <code title="post /proxies">client.Proxies.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#ProxyService.New">New</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, body <a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#ProxyNewParams">ProxyNewParams</a>) (<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#ProxyNewResponse">ProxyNewResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
212213
- <code title="get /proxies/{id}">client.Proxies.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#ProxyService.Get">Get</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#ProxyGetResponse">ProxyGetResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
213214
- <code title="get /proxies">client.Proxies.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#ProxyService.List">List</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>) ([]<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#ProxyListResponse">ProxyListResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
214215
- <code title="delete /proxies/{id}">client.Proxies.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#ProxyService.Delete">Delete</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) <a href="https://pkg.go.dev/builtin#error">error</a></code>
216+
- <code title="post /proxies/{id}/check">client.Proxies.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#ProxyService.Check">Check</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#ProxyCheckResponse">ProxyCheckResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
215217

216218
# Extensions
217219

proxy.go

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@ func (r *ProxyService) Delete(ctx context.Context, id string, opts ...option.Req
7878
return
7979
}
8080

81+
// Run a health check on the proxy to verify it's working.
82+
func (r *ProxyService) Check(ctx context.Context, id string, opts ...option.RequestOption) (res *ProxyCheckResponse, err error) {
83+
opts = slices.Concat(r.Options, opts)
84+
if id == "" {
85+
err = errors.New("missing required id parameter")
86+
return
87+
}
88+
path := fmt.Sprintf("proxies/%s/check", id)
89+
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...)
90+
return
91+
}
92+
8193
// Configuration for routing traffic through a proxy.
8294
type ProxyNewResponse struct {
8395
// Proxy type to use. In terms of quality for avoiding bot-detection, from best to
@@ -942,6 +954,294 @@ const (
942954
ProxyListResponseStatusUnavailable ProxyListResponseStatus = "unavailable"
943955
)
944956

957+
// Configuration for routing traffic through a proxy.
958+
type ProxyCheckResponse struct {
959+
// Proxy type to use. In terms of quality for avoiding bot-detection, from best to
960+
// worst: `mobile` > `residential` > `isp` > `datacenter`.
961+
//
962+
// Any of "datacenter", "isp", "residential", "mobile", "custom".
963+
Type ProxyCheckResponseType `json:"type,required"`
964+
ID string `json:"id"`
965+
// Configuration specific to the selected proxy `type`.
966+
Config ProxyCheckResponseConfigUnion `json:"config"`
967+
// Timestamp of the last health check performed on this proxy.
968+
LastChecked time.Time `json:"last_checked" format:"date-time"`
969+
// Readable name of the proxy.
970+
Name string `json:"name"`
971+
// Protocol to use for the proxy connection.
972+
//
973+
// Any of "http", "https".
974+
Protocol ProxyCheckResponseProtocol `json:"protocol"`
975+
// Current health status of the proxy.
976+
//
977+
// Any of "available", "unavailable".
978+
Status ProxyCheckResponseStatus `json:"status"`
979+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
980+
JSON struct {
981+
Type respjson.Field
982+
ID respjson.Field
983+
Config respjson.Field
984+
LastChecked respjson.Field
985+
Name respjson.Field
986+
Protocol respjson.Field
987+
Status respjson.Field
988+
ExtraFields map[string]respjson.Field
989+
raw string
990+
} `json:"-"`
991+
}
992+
993+
// Returns the unmodified JSON received from the API
994+
func (r ProxyCheckResponse) RawJSON() string { return r.JSON.raw }
995+
func (r *ProxyCheckResponse) UnmarshalJSON(data []byte) error {
996+
return apijson.UnmarshalRoot(data, r)
997+
}
998+
999+
// Proxy type to use. In terms of quality for avoiding bot-detection, from best to
1000+
// worst: `mobile` > `residential` > `isp` > `datacenter`.
1001+
type ProxyCheckResponseType string
1002+
1003+
const (
1004+
ProxyCheckResponseTypeDatacenter ProxyCheckResponseType = "datacenter"
1005+
ProxyCheckResponseTypeIsp ProxyCheckResponseType = "isp"
1006+
ProxyCheckResponseTypeResidential ProxyCheckResponseType = "residential"
1007+
ProxyCheckResponseTypeMobile ProxyCheckResponseType = "mobile"
1008+
ProxyCheckResponseTypeCustom ProxyCheckResponseType = "custom"
1009+
)
1010+
1011+
// ProxyCheckResponseConfigUnion contains all possible properties and values from
1012+
// [ProxyCheckResponseConfigDatacenterProxyConfig],
1013+
// [ProxyCheckResponseConfigIspProxyConfig],
1014+
// [ProxyCheckResponseConfigResidentialProxyConfig],
1015+
// [ProxyCheckResponseConfigMobileProxyConfig],
1016+
// [ProxyCheckResponseConfigCustomProxyConfig].
1017+
//
1018+
// Use the methods beginning with 'As' to cast the union to one of its variants.
1019+
type ProxyCheckResponseConfigUnion struct {
1020+
Country string `json:"country"`
1021+
Asn string `json:"asn"`
1022+
City string `json:"city"`
1023+
// This field is from variant [ProxyCheckResponseConfigResidentialProxyConfig].
1024+
Os string `json:"os"`
1025+
State string `json:"state"`
1026+
Zip string `json:"zip"`
1027+
// This field is from variant [ProxyCheckResponseConfigMobileProxyConfig].
1028+
Carrier string `json:"carrier"`
1029+
// This field is from variant [ProxyCheckResponseConfigCustomProxyConfig].
1030+
Host string `json:"host"`
1031+
// This field is from variant [ProxyCheckResponseConfigCustomProxyConfig].
1032+
Port int64 `json:"port"`
1033+
// This field is from variant [ProxyCheckResponseConfigCustomProxyConfig].
1034+
HasPassword bool `json:"has_password"`
1035+
// This field is from variant [ProxyCheckResponseConfigCustomProxyConfig].
1036+
Username string `json:"username"`
1037+
JSON struct {
1038+
Country respjson.Field
1039+
Asn respjson.Field
1040+
City respjson.Field
1041+
Os respjson.Field
1042+
State respjson.Field
1043+
Zip respjson.Field
1044+
Carrier respjson.Field
1045+
Host respjson.Field
1046+
Port respjson.Field
1047+
HasPassword respjson.Field
1048+
Username respjson.Field
1049+
raw string
1050+
} `json:"-"`
1051+
}
1052+
1053+
func (u ProxyCheckResponseConfigUnion) AsProxyCheckResponseConfigDatacenterProxyConfig() (v ProxyCheckResponseConfigDatacenterProxyConfig) {
1054+
apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1055+
return
1056+
}
1057+
1058+
func (u ProxyCheckResponseConfigUnion) AsProxyCheckResponseConfigIspProxyConfig() (v ProxyCheckResponseConfigIspProxyConfig) {
1059+
apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1060+
return
1061+
}
1062+
1063+
func (u ProxyCheckResponseConfigUnion) AsProxyCheckResponseConfigResidentialProxyConfig() (v ProxyCheckResponseConfigResidentialProxyConfig) {
1064+
apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1065+
return
1066+
}
1067+
1068+
func (u ProxyCheckResponseConfigUnion) AsProxyCheckResponseConfigMobileProxyConfig() (v ProxyCheckResponseConfigMobileProxyConfig) {
1069+
apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1070+
return
1071+
}
1072+
1073+
func (u ProxyCheckResponseConfigUnion) AsProxyCheckResponseConfigCustomProxyConfig() (v ProxyCheckResponseConfigCustomProxyConfig) {
1074+
apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
1075+
return
1076+
}
1077+
1078+
// Returns the unmodified JSON received from the API
1079+
func (u ProxyCheckResponseConfigUnion) RawJSON() string { return u.JSON.raw }
1080+
1081+
func (r *ProxyCheckResponseConfigUnion) UnmarshalJSON(data []byte) error {
1082+
return apijson.UnmarshalRoot(data, r)
1083+
}
1084+
1085+
// Configuration for a datacenter proxy.
1086+
type ProxyCheckResponseConfigDatacenterProxyConfig struct {
1087+
// ISO 3166 country code. Defaults to US if not provided.
1088+
Country string `json:"country"`
1089+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
1090+
JSON struct {
1091+
Country respjson.Field
1092+
ExtraFields map[string]respjson.Field
1093+
raw string
1094+
} `json:"-"`
1095+
}
1096+
1097+
// Returns the unmodified JSON received from the API
1098+
func (r ProxyCheckResponseConfigDatacenterProxyConfig) RawJSON() string { return r.JSON.raw }
1099+
func (r *ProxyCheckResponseConfigDatacenterProxyConfig) UnmarshalJSON(data []byte) error {
1100+
return apijson.UnmarshalRoot(data, r)
1101+
}
1102+
1103+
// Configuration for an ISP proxy.
1104+
type ProxyCheckResponseConfigIspProxyConfig struct {
1105+
// ISO 3166 country code. Defaults to US if not provided.
1106+
Country string `json:"country"`
1107+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
1108+
JSON struct {
1109+
Country respjson.Field
1110+
ExtraFields map[string]respjson.Field
1111+
raw string
1112+
} `json:"-"`
1113+
}
1114+
1115+
// Returns the unmodified JSON received from the API
1116+
func (r ProxyCheckResponseConfigIspProxyConfig) RawJSON() string { return r.JSON.raw }
1117+
func (r *ProxyCheckResponseConfigIspProxyConfig) UnmarshalJSON(data []byte) error {
1118+
return apijson.UnmarshalRoot(data, r)
1119+
}
1120+
1121+
// Configuration for residential proxies.
1122+
type ProxyCheckResponseConfigResidentialProxyConfig struct {
1123+
// Autonomous system number. See https://bgp.potaroo.net/cidr/autnums.html
1124+
Asn string `json:"asn"`
1125+
// City name (no spaces, e.g. `sanfrancisco`). If provided, `country` must also be
1126+
// provided.
1127+
City string `json:"city"`
1128+
// ISO 3166 country code.
1129+
Country string `json:"country"`
1130+
// Operating system of the residential device.
1131+
//
1132+
// Any of "windows", "macos", "android".
1133+
//
1134+
// Deprecated: deprecated
1135+
Os string `json:"os"`
1136+
// Two-letter state code.
1137+
State string `json:"state"`
1138+
// US ZIP code.
1139+
Zip string `json:"zip"`
1140+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
1141+
JSON struct {
1142+
Asn respjson.Field
1143+
City respjson.Field
1144+
Country respjson.Field
1145+
Os respjson.Field
1146+
State respjson.Field
1147+
Zip respjson.Field
1148+
ExtraFields map[string]respjson.Field
1149+
raw string
1150+
} `json:"-"`
1151+
}
1152+
1153+
// Returns the unmodified JSON received from the API
1154+
func (r ProxyCheckResponseConfigResidentialProxyConfig) RawJSON() string { return r.JSON.raw }
1155+
func (r *ProxyCheckResponseConfigResidentialProxyConfig) UnmarshalJSON(data []byte) error {
1156+
return apijson.UnmarshalRoot(data, r)
1157+
}
1158+
1159+
// Configuration for mobile proxies.
1160+
type ProxyCheckResponseConfigMobileProxyConfig struct {
1161+
// Autonomous system number. See https://bgp.potaroo.net/cidr/autnums.html
1162+
Asn string `json:"asn"`
1163+
// Mobile carrier.
1164+
//
1165+
// Any of "a1", "aircel", "airtel", "att", "celcom", "chinamobile", "claro",
1166+
// "comcast", "cox", "digi", "dt", "docomo", "dtac", "etisalat", "idea",
1167+
// "kyivstar", "meo", "megafon", "mtn", "mtnza", "mts", "optus", "orange", "qwest",
1168+
// "reliance_jio", "robi", "sprint", "telefonica", "telstra", "tmobile", "tigo",
1169+
// "tim", "verizon", "vimpelcom", "vodacomza", "vodafone", "vivo", "zain",
1170+
// "vivabo", "telenormyanmar", "kcelljsc", "swisscom", "singtel", "asiacell",
1171+
// "windit", "cellc", "ooredoo", "drei", "umobile", "cableone", "proximus",
1172+
// "tele2", "mobitel", "o2", "bouygues", "free", "sfr", "digicel".
1173+
Carrier string `json:"carrier"`
1174+
// City name (no spaces, e.g. `sanfrancisco`). If provided, `country` must also be
1175+
// provided.
1176+
City string `json:"city"`
1177+
// ISO 3166 country code
1178+
Country string `json:"country"`
1179+
// Two-letter state code.
1180+
State string `json:"state"`
1181+
// US ZIP code.
1182+
Zip string `json:"zip"`
1183+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
1184+
JSON struct {
1185+
Asn respjson.Field
1186+
Carrier respjson.Field
1187+
City respjson.Field
1188+
Country respjson.Field
1189+
State respjson.Field
1190+
Zip respjson.Field
1191+
ExtraFields map[string]respjson.Field
1192+
raw string
1193+
} `json:"-"`
1194+
}
1195+
1196+
// Returns the unmodified JSON received from the API
1197+
func (r ProxyCheckResponseConfigMobileProxyConfig) RawJSON() string { return r.JSON.raw }
1198+
func (r *ProxyCheckResponseConfigMobileProxyConfig) UnmarshalJSON(data []byte) error {
1199+
return apijson.UnmarshalRoot(data, r)
1200+
}
1201+
1202+
// Configuration for a custom proxy (e.g., private proxy server).
1203+
type ProxyCheckResponseConfigCustomProxyConfig struct {
1204+
// Proxy host address or IP.
1205+
Host string `json:"host,required"`
1206+
// Proxy port.
1207+
Port int64 `json:"port,required"`
1208+
// Whether the proxy has a password.
1209+
HasPassword bool `json:"has_password"`
1210+
// Username for proxy authentication.
1211+
Username string `json:"username"`
1212+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
1213+
JSON struct {
1214+
Host respjson.Field
1215+
Port respjson.Field
1216+
HasPassword respjson.Field
1217+
Username respjson.Field
1218+
ExtraFields map[string]respjson.Field
1219+
raw string
1220+
} `json:"-"`
1221+
}
1222+
1223+
// Returns the unmodified JSON received from the API
1224+
func (r ProxyCheckResponseConfigCustomProxyConfig) RawJSON() string { return r.JSON.raw }
1225+
func (r *ProxyCheckResponseConfigCustomProxyConfig) UnmarshalJSON(data []byte) error {
1226+
return apijson.UnmarshalRoot(data, r)
1227+
}
1228+
1229+
// Protocol to use for the proxy connection.
1230+
type ProxyCheckResponseProtocol string
1231+
1232+
const (
1233+
ProxyCheckResponseProtocolHTTP ProxyCheckResponseProtocol = "http"
1234+
ProxyCheckResponseProtocolHTTPS ProxyCheckResponseProtocol = "https"
1235+
)
1236+
1237+
// Current health status of the proxy.
1238+
type ProxyCheckResponseStatus string
1239+
1240+
const (
1241+
ProxyCheckResponseStatusAvailable ProxyCheckResponseStatus = "available"
1242+
ProxyCheckResponseStatusUnavailable ProxyCheckResponseStatus = "unavailable"
1243+
)
1244+
9451245
type ProxyNewParams struct {
9461246
// Proxy type to use. In terms of quality for avoiding bot-detection, from best to
9471247
// worst: `mobile` > `residential` > `isp` > `datacenter`.

proxy_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,26 @@ func TestProxyDelete(t *testing.T) {
113113
t.Fatalf("err should be nil: %s", err.Error())
114114
}
115115
}
116+
117+
func TestProxyCheck(t *testing.T) {
118+
t.Skip("Prism tests are disabled")
119+
baseURL := "http://localhost:4010"
120+
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
121+
baseURL = envURL
122+
}
123+
if !testutil.CheckTestServer(t, baseURL) {
124+
return
125+
}
126+
client := kernel.NewClient(
127+
option.WithBaseURL(baseURL),
128+
option.WithAPIKey("My API Key"),
129+
)
130+
_, err := client.Proxies.Check(context.TODO(), "id")
131+
if err != nil {
132+
var apierr *kernel.Error
133+
if errors.As(err, &apierr) {
134+
t.Log(string(apierr.DumpRequest(true)))
135+
}
136+
t.Fatalf("err should be nil: %s", err.Error())
137+
}
138+
}

0 commit comments

Comments
 (0)