@@ -9,6 +9,10 @@ import (
99
1010 "github.com/zclconf/go-cty/cty"
1111 "github.com/zclconf/go-cty/cty/msgpack"
12+ "go.opentelemetry.io/otel"
13+ "go.opentelemetry.io/otel/attribute"
14+ "go.opentelemetry.io/otel/codes"
15+ "go.opentelemetry.io/otel/trace"
1216 "google.golang.org/grpc"
1317
1418 "github.com/hashicorp/terraform/internal/policy/proto"
@@ -18,59 +22,104 @@ var (
1822 _ proto.CallbackServiceServer = (* Server )(nil )
1923)
2024
25+ // tracer is resolved lazily so the global TracerProvider installed by
26+ // openTelemetryInit (which runs after package init) is reflected.
27+ func tracer () trace.Tracer {
28+ return otel .Tracer ("github.com/hashicorp/terraform/internal/policy/callback" )
29+ }
30+
2131type Server struct {
2232 ID uint32
2333 Registry Registry
2434 Grpc * grpc.Server
2535 proto.UnimplementedCallbackServiceServer
2636}
2737
28- func (s * Server ) GetResources (_ context.Context , request * proto.GetResourcesRequest ) (* proto.GetResourcesResponse , error ) {
38+ func (s * Server ) GetResources (ctx context.Context , request * proto.GetResourcesRequest ) (* proto.GetResourcesResponse , error ) {
39+ ctx , span := tracer ().Start (ctx , "policy.callback.server.get_resources" ,
40+ trace .WithAttributes (
41+ attribute .String ("policy.callback.resource_type" , request .Type ),
42+ attribute .Int64 ("policy.evaluation.id" , int64 (request .EvaluationRequestId )),
43+ ),
44+ )
45+ defer span .End ()
46+
2947 attrs , err := msgpack .Unmarshal (request .Attributes , cty .DynamicPseudoType )
3048 if err != nil {
31- return nil , fmt .Errorf ("failed to unserialize attributes: %w" , err )
49+ err = fmt .Errorf ("failed to unserialize attributes: %w" , err )
50+ span .RecordError (err )
51+ span .SetStatus (codes .Error , err .Error ())
52+ return nil , err
3253 }
3354 functions , ok := s .Registry .Get (request .EvaluationRequestId )
3455 if ! ok {
35- return nil , fmt .Errorf ("no callback registered for ID %d (request type: %s)" , request .EvaluationRequestId , request .Type )
56+ err := fmt .Errorf ("no callback registered for ID %d (request type: %s)" , request .EvaluationRequestId , request .Type )
57+ span .RecordError (err )
58+ span .SetStatus (codes .Error , err .Error ())
59+ return nil , err
3660 }
37- resources , err := functions .GetResources (request .Type , attrs )
61+ resources , err := functions .GetResources (ctx , request .Type , attrs )
3862 if err != nil {
63+ span .RecordError (err )
64+ span .SetStatus (codes .Error , err .Error ())
3965 return nil , err
4066 }
4167
4268 results := make ([][]byte , 0 , len (resources ))
4369 for _ , resource := range resources {
4470 result , err := msgpack .Marshal (resource , cty .DynamicPseudoType )
4571 if err != nil {
46- return nil , fmt .Errorf ("failed to serialize resource: %w" , err )
72+ err = fmt .Errorf ("failed to serialize resource: %w" , err )
73+ span .RecordError (err )
74+ span .SetStatus (codes .Error , err .Error ())
75+ return nil , err
4776 }
4877 results = append (results , result )
4978 }
5079
80+ span .SetAttributes (attribute .Int ("policy.callback.results.count" , len (results )))
5181 return & proto.GetResourcesResponse {
5282 Results : results ,
5383 }, nil
5484}
5585
56- func (s * Server ) GetDataSource (_ context.Context , request * proto.GetDataSourceRequest ) (* proto.GetDataSourceResponse , error ) {
86+ func (s * Server ) GetDataSource (ctx context.Context , request * proto.GetDataSourceRequest ) (* proto.GetDataSourceResponse , error ) {
87+ ctx , span := tracer ().Start (ctx , "policy.callback.server.get_datasource" ,
88+ trace .WithAttributes (
89+ attribute .String ("policy.callback.datasource_type" , request .Type ),
90+ attribute .Int64 ("policy.evaluation.id" , int64 (request .EvaluationRequestId )),
91+ ),
92+ )
93+ defer span .End ()
94+
5795 config , err := msgpack .Unmarshal (request .Config , cty .DynamicPseudoType )
5896 if err != nil {
59- return nil , fmt .Errorf ("failed to unserialize config: %w" , err )
97+ err = fmt .Errorf ("failed to unserialize config: %w" , err )
98+ span .RecordError (err )
99+ span .SetStatus (codes .Error , err .Error ())
100+ return nil , err
60101 }
61102
62103 functions , ok := s .Registry .Get (request .EvaluationRequestId )
63104 if ! ok {
64- return nil , fmt .Errorf ("no callback registered for ID %d (request type: %s)" , request .EvaluationRequestId , request .Type )
105+ err := fmt .Errorf ("no callback registered for ID %d (request type: %s)" , request .EvaluationRequestId , request .Type )
106+ span .RecordError (err )
107+ span .SetStatus (codes .Error , err .Error ())
108+ return nil , err
65109 }
66- datasource , err := functions .GetDataSource (request .Type , config )
110+ datasource , err := functions .GetDataSource (ctx , request .Type , config )
67111 if err != nil {
112+ span .RecordError (err )
113+ span .SetStatus (codes .Error , err .Error ())
68114 return nil , err
69115 }
70116
71117 result , err := msgpack .Marshal (datasource , cty .DynamicPseudoType )
72118 if err != nil {
73- return nil , fmt .Errorf ("failed to serialize datasource: %w" , err )
119+ err = fmt .Errorf ("failed to serialize datasource: %w" , err )
120+ span .RecordError (err )
121+ span .SetStatus (codes .Error , err .Error ())
122+ return nil , err
74123 }
75124
76125 return & proto.GetDataSourceResponse {
0 commit comments