Skip to content
Draft
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
8 changes: 8 additions & 0 deletions internal/api/apitest/mock_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type MockClient struct {
UpdateConversationFunc func(ctx context.Context, id string, input gen.UpdateConversationInput) (*gen.UpdateConversationResponse, error)
DeleteConversationFunc func(ctx context.Context, id string) (*gen.DeleteConversationResponse, error)
CreateMessageFunc func(ctx context.Context, input gen.CreateMessageInput) (*gen.CreateMessageResponse, error)
ApproveLogEventPolicyFunc func(ctx context.Context, id string) (*gen.ApproveLogEventPolicyResponse, error)
}

// NewMockClient creates a MockClient with sensible defaults.
Expand Down Expand Up @@ -134,3 +135,10 @@ func (m *MockClient) CreateMessage(ctx context.Context, input gen.CreateMessageI
}
return nil, nil
}

func (m *MockClient) ApproveLogEventPolicy(ctx context.Context, id string) (*gen.ApproveLogEventPolicyResponse, error) {
if m.ApproveLogEventPolicyFunc != nil {
return m.ApproveLogEventPolicyFunc(ctx, id)
}
return nil, nil
}
22 changes: 22 additions & 0 deletions internal/api/apitest/mock_policies.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package apitest

import (
"context"
)

// MockPolicies implements api.LogEventPolicies for testing.
type MockPolicies struct {
ApproveFunc func(ctx context.Context, id string) error
}

// NewMockPolicies creates a MockPolicies with sensible defaults.
func NewMockPolicies() *MockPolicies {
return &MockPolicies{}
}

func (m *MockPolicies) Approve(ctx context.Context, id string) error {
if m.ApproveFunc != nil {
return m.ApproveFunc(ctx, id)
}
return nil
}
13 changes: 13 additions & 0 deletions internal/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ type Client interface {

// Message operations
CreateMessage(ctx context.Context, input gen.CreateMessageInput) (*gen.CreateMessageResponse, error)

// Policy operations
ApproveLogEventPolicy(ctx context.Context, id string) (*gen.ApproveLogEventPolicyResponse, error)
}

// client is the concrete implementation of Client.
Expand Down Expand Up @@ -261,3 +264,13 @@ func (c *client) CreateMessage(ctx context.Context, input gen.CreateMessageInput
}
return gen.CreateMessage(ctx, gql, input)
}

// Policy operations

func (c *client) ApproveLogEventPolicy(ctx context.Context, id string) (*gen.ApproveLogEventPolicyResponse, error) {
gql, err := c.gql(ctx)
if err != nil {
return nil, err
}
return gen.ApproveLogEventPolicy(ctx, gql, id)
}
164 changes: 164 additions & 0 deletions internal/api/gen/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions internal/api/gen/queries/policies.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
mutation ApproveLogEventPolicy($id: ID!) {
approveLogEventPolicy(id: $id) {
id
category
approvedAt
approvedBy
}
}

mutation DismissLogEventPolicy($id: ID!) {
dismissLogEventPolicy(id: $id) {
id
category
dismissedAt
dismissedBy
}
}
47 changes: 47 additions & 0 deletions internal/api/policy_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package api

import (
"context"
"fmt"

"github.com/usetero/cli/internal/log"
)

// LogEventPolicies provides access to log event policy operations.
type LogEventPolicies interface {
Approve(ctx context.Context, id string) error
}

// PolicyService handles policy-related API operations.
type PolicyService struct {
client Client
scope log.Scope
}

// Ensure PolicyService implements LogEventPolicies.
var _ LogEventPolicies = (*PolicyService)(nil)

// NewPolicyService creates a new policy service.
func NewPolicyService(client Client, scope log.Scope) *PolicyService {
return &PolicyService{
client: client,
scope: scope.Child("policies"),
}
}

// Approve approves a log event policy.
func (s *PolicyService) Approve(ctx context.Context, id string) error {
s.scope.Debug("approving policy via API", "id", id)

_, err := s.client.ApproveLogEventPolicy(ctx, id)
if err != nil {
s.scope.Error("failed to approve policy", "error", err, "id", id)
if classified := classifyError(err); classified != nil {
return fmt.Errorf("approve policy %s: %w", id, classified)
}
return err
}

s.scope.Debug("approved policy via API", "id", id)
return nil
}
2 changes: 2 additions & 0 deletions internal/api/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type APIServices struct {
DatadogAccounts DatadogAccounts
Conversations Conversations
Messages Messages
Policies LogEventPolicies
}

// NewServices creates APIServices with an internally-managed client.
Expand All @@ -43,6 +44,7 @@ func newAPIServices(client Client, scope log.Scope) APIServices {
DatadogAccounts: NewDatadogAccountService(client, scope),
Conversations: NewConversationService(client, scope),
Messages: NewMessageService(client, scope),
Policies: NewPolicyService(client, scope),
}
}

Expand Down
Loading