diff --git a/agent/internal/checker/checker.go b/agent/internal/checker/checker.go index c4d49dd..547f165 100644 --- a/agent/internal/checker/checker.go +++ b/agent/internal/checker/checker.go @@ -34,6 +34,7 @@ type Spec struct { ExpectedStatus int Keyword string TLSWarnDays int + Insecure bool // skip TLS certificate verification (HTTP checks) TimeoutSec int } @@ -79,6 +80,9 @@ func runHTTP(ctx context.Context, s Spec) Result { expect = 200 } client := &http.Client{Timeout: s.timeout()} + if s.Insecure { + client.Transport = &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} //nolint:gosec // opt-in per monitor + } start := time.Now() req, err := http.NewRequestWithContext(ctx, method, s.URL, nil) if err != nil { diff --git a/agent/internal/grpc/pb/vantage.pb.go b/agent/internal/grpc/pb/vantage.pb.go index 723b59e..2cb692d 100644 --- a/agent/internal/grpc/pb/vantage.pb.go +++ b/agent/internal/grpc/pb/vantage.pb.go @@ -104,6 +104,7 @@ type MonitorSpec struct { ExpectedStatus int `json:"expected_status,omitempty"` Keyword string `json:"keyword,omitempty"` TLSWarnDays int `json:"tls_warn_days,omitempty"` + Insecure bool `json:"insecure,omitempty"` IntervalSec int `json:"interval_sec"` Retries int `json:"retries"` } diff --git a/agent/internal/monitors/monitors.go b/agent/internal/monitors/monitors.go index 69f76a4..242259e 100644 --- a/agent/internal/monitors/monitors.go +++ b/agent/internal/monitors/monitors.go @@ -99,6 +99,7 @@ func runSpec(ctx context.Context, s pb.MonitorSpec, out chan<- pb.CheckResult) { ExpectedStatus: s.ExpectedStatus, Keyword: s.Keyword, TLSWarnDays: s.TLSWarnDays, + Insecure: s.Insecure, TimeoutSec: s.IntervalSec, } diff --git a/proto/vantage/v1/vantage.proto b/proto/vantage/v1/vantage.proto index e5fda50..9cf22ec 100644 --- a/proto/vantage/v1/vantage.proto +++ b/proto/vantage/v1/vantage.proto @@ -131,6 +131,7 @@ message MonitorSpec { int32 tls_warn_days = 9; int32 interval_sec = 10; int32 retries = 11; + bool insecure = 12; } message SyncMonitorsRequest { diff --git a/server/internal/checker/checker.go b/server/internal/checker/checker.go index c4d49dd..547f165 100644 --- a/server/internal/checker/checker.go +++ b/server/internal/checker/checker.go @@ -34,6 +34,7 @@ type Spec struct { ExpectedStatus int Keyword string TLSWarnDays int + Insecure bool // skip TLS certificate verification (HTTP checks) TimeoutSec int } @@ -79,6 +80,9 @@ func runHTTP(ctx context.Context, s Spec) Result { expect = 200 } client := &http.Client{Timeout: s.timeout()} + if s.Insecure { + client.Transport = &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} //nolint:gosec // opt-in per monitor + } start := time.Now() req, err := http.NewRequestWithContext(ctx, method, s.URL, nil) if err != nil { diff --git a/server/internal/grpc/pb/vantage.pb.go b/server/internal/grpc/pb/vantage.pb.go index 3cf3882..6dcb766 100644 --- a/server/internal/grpc/pb/vantage.pb.go +++ b/server/internal/grpc/pb/vantage.pb.go @@ -107,6 +107,7 @@ type MonitorSpec struct { ExpectedStatus int `json:"expected_status,omitempty"` Keyword string `json:"keyword,omitempty"` TLSWarnDays int `json:"tls_warn_days,omitempty"` + Insecure bool `json:"insecure,omitempty"` IntervalSec int `json:"interval_sec"` Retries int `json:"retries"` } diff --git a/server/internal/grpc/server.go b/server/internal/grpc/server.go index e7888b6..3351998 100644 --- a/server/internal/grpc/server.go +++ b/server/internal/grpc/server.go @@ -128,6 +128,7 @@ func (s *vantageServer) SyncMonitors(ctx context.Context, req *pb.SyncMonitorsRe ExpectedStatus: m.Target.ExpectedStatus, Keyword: m.Target.Keyword, TLSWarnDays: m.Target.TLSWarnDays, + Insecure: m.Target.Insecure, IntervalSec: m.IntervalSec, Retries: m.Retries, }) diff --git a/server/internal/models/monitor.go b/server/internal/models/monitor.go index 78b9978..472df32 100644 --- a/server/internal/models/monitor.go +++ b/server/internal/models/monitor.go @@ -33,6 +33,7 @@ type MonitorTarget struct { ExpectedStatus int `bson:"expected_status,omitempty" json:"expected_status,omitempty"` Keyword string `bson:"keyword,omitempty" json:"keyword,omitempty"` TLSWarnDays int `bson:"tls_warn_days,omitempty" json:"tls_warn_days,omitempty"` + Insecure bool `bson:"insecure,omitempty" json:"insecure,omitempty"` // skip TLS cert verification (HTTP monitors) } type MonitorState struct { diff --git a/server/internal/services/monitors.go b/server/internal/services/monitors.go index 992d414..b72d146 100644 --- a/server/internal/services/monitors.go +++ b/server/internal/services/monitors.go @@ -31,6 +31,7 @@ func SpecFor(m *models.Monitor) checker.Spec { ExpectedStatus: m.Target.ExpectedStatus, Keyword: m.Target.Keyword, TLSWarnDays: m.Target.TLSWarnDays, + Insecure: m.Target.Insecure, TimeoutSec: m.IntervalSec, } } diff --git a/web/app/monitors/[id]/edit/page.tsx b/web/app/monitors/[id]/edit/page.tsx new file mode 100644 index 0000000..8a6b3f8 --- /dev/null +++ b/web/app/monitors/[id]/edit/page.tsx @@ -0,0 +1,58 @@ +"use client"; + +import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; +import { useParams, useRouter } from "next/navigation"; +import Link from "next/link"; +import { api, MonitorInput } from "@/lib/api"; +import { Card } from "@/components/ui"; +import { MonitorForm } from "@/components/monitors/MonitorForm"; + +export default function EditMonitorPage() { + const params = useParams(); + const router = useRouter(); + const queryClient = useQueryClient(); + const monitorId = params.id as string; + + const { data: monitor, isLoading } = useQuery({ + queryKey: ["monitors", monitorId], + queryFn: () => api.getMonitor(monitorId), + }); + + const { mutate: update, isPending, error } = useMutation({ + mutationFn: (input: MonitorInput) => api.updateMonitor(monitorId, input), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["monitors"] }); + queryClient.invalidateQueries({ queryKey: ["monitors", monitorId] }); + router.push(`/monitors/${monitorId}`); + }, + }); + + if (isLoading) { + return ( +
{monitor.state.message}
}