VA: Make performRemoteValidation more generic (#7847)
- Make performRemoteValidation a more generic function that returns a new remoteResult interface - Modify the return value of IsCAAValid and PerformValidation to satisfy the remoteResult interface - Include compile time checks and tests that pass an arbitrary operation
This commit is contained in:
parent
ded2e5e610
commit
27a77142ad
|
|
@ -188,13 +188,13 @@ func ValidationResultToPB(records []core.ValidationRecord, prob *probs.ProblemDe
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
marshalledProbs, err := ProblemDetailsToPB(prob)
|
||||
marshalledProb, err := ProblemDetailsToPB(prob)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &vapb.ValidationResult{
|
||||
Records: recordAry,
|
||||
Problems: marshalledProbs,
|
||||
Problem: marshalledProb,
|
||||
Perspective: perspective,
|
||||
Rir: rir,
|
||||
}, nil
|
||||
|
|
@ -212,7 +212,7 @@ func pbToValidationResult(in *vapb.ValidationResult) ([]core.ValidationRecord, *
|
|||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
prob, err := PBToProblemDetails(in.Problems)
|
||||
prob, err := PBToProblemDetails(in.Problem)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
|
|||
6
ra/ra.go
6
ra/ra.go
|
|
@ -1762,7 +1762,7 @@ func (ra *RegistrationAuthorityImpl) recordValidation(ctx context.Context, authI
|
|||
Attempted: string(challenge.Type),
|
||||
AttemptedAt: validated,
|
||||
ValidationRecords: vr.Records,
|
||||
ValidationError: vr.Problems,
|
||||
ValidationError: vr.Problem,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
|
@ -1929,8 +1929,8 @@ func (ra *RegistrationAuthorityImpl) PerformValidation(
|
|||
prob = probs.ServerInternal("Could not communicate with VA")
|
||||
ra.log.AuditErrf("Could not communicate with VA: %s", err)
|
||||
} else {
|
||||
if res.Problems != nil {
|
||||
prob, err = bgrpc.PBToProblemDetails(res.Problems)
|
||||
if res.Problem != nil {
|
||||
prob, err = bgrpc.PBToProblemDetails(res.Problem)
|
||||
if err != nil {
|
||||
prob = probs.ServerInternal("Could not communicate with VA")
|
||||
ra.log.AuditErrf("Could not communicate with VA: %s", err)
|
||||
|
|
|
|||
|
|
@ -728,7 +728,7 @@ func TestPerformValidationAlreadyValid(t *testing.T) {
|
|||
Url: "http://example.com/",
|
||||
},
|
||||
},
|
||||
Problems: nil,
|
||||
Problem: nil,
|
||||
}
|
||||
|
||||
// A subsequent call to perform validation should return nil due
|
||||
|
|
@ -758,7 +758,7 @@ func TestPerformValidationSuccess(t *testing.T) {
|
|||
ResolverAddrs: []string{"rebound"},
|
||||
},
|
||||
},
|
||||
Problems: nil,
|
||||
Problem: nil,
|
||||
}
|
||||
|
||||
now := fc.Now()
|
||||
|
|
@ -901,7 +901,7 @@ func TestPerformValidation_FailedValidationsTriggerPauseIdentifiersRatelimit(t *
|
|||
ResolverAddrs: []string{"rebound"},
|
||||
},
|
||||
},
|
||||
Problems: &corepb.ProblemDetails{
|
||||
Problem: &corepb.ProblemDetails{
|
||||
Detail: fmt.Sprintf("CAA invalid for %s", domain),
|
||||
},
|
||||
}
|
||||
|
|
@ -954,7 +954,7 @@ func TestPerformValidation_FailedValidationsTriggerPauseIdentifiersRatelimit(t *
|
|||
ResolverAddrs: []string{"rebound"},
|
||||
},
|
||||
},
|
||||
Problems: &corepb.ProblemDetails{
|
||||
Problem: &corepb.ProblemDetails{
|
||||
Detail: fmt.Sprintf("CAA invalid for %s", domain),
|
||||
},
|
||||
}
|
||||
|
|
@ -1034,7 +1034,7 @@ func TestPerformValidation_FailedThenSuccessfulValidationResetsPauseIdentifiersR
|
|||
ResolverAddrs: []string{"rebound"},
|
||||
},
|
||||
},
|
||||
Problems: &corepb.ProblemDetails{
|
||||
Problem: &corepb.ProblemDetails{
|
||||
Detail: fmt.Sprintf("CAA invalid for %s", domain),
|
||||
},
|
||||
}
|
||||
|
|
@ -1092,7 +1092,7 @@ func TestPerformValidation_FailedThenSuccessfulValidationResetsPauseIdentifiersR
|
|||
ResolverAddrs: []string{"rebound"},
|
||||
},
|
||||
},
|
||||
Problems: nil,
|
||||
Problem: nil,
|
||||
}
|
||||
|
||||
challIdx = dnsChallIdx(t, authzPB.Challenges)
|
||||
|
|
|
|||
|
|
@ -1083,8 +1083,8 @@ def test_http_multiva_threshold_fail():
|
|||
raise(Exception("no HTTP-01 challenge in failed authz"))
|
||||
if httpChall.error.typ != "urn:ietf:params:acme:error:unauthorized":
|
||||
raise(Exception("expected unauthorized prob, found {0}".format(httpChall.error.typ)))
|
||||
if not httpChall.error.detail.startswith("During secondary domain validation: "):
|
||||
raise(Exception("expected 'During secondary domain validation' problem detail, found {0}".format(httpChall.error.detail)))
|
||||
if not httpChall.error.detail.startswith("During secondary validation: "):
|
||||
raise(Exception("expected 'During secondary validation' problem detail, found {0}".format(httpChall.error.detail)))
|
||||
|
||||
class FakeH2ServerHandler(socketserver.BaseRequestHandler):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ func TestDNSValidationEmpty(t *testing.T) {
|
|||
// metrics checked below are incremented.
|
||||
req := createValidationRequest("empty-txts.com", core.ChallengeTypeDNS01)
|
||||
res, _ := va.PerformValidation(context.Background(), req)
|
||||
test.AssertEquals(t, res.Problems.ProblemType, "unauthorized")
|
||||
test.AssertEquals(t, res.Problems.Detail, "No TXT record found at _acme-challenge.empty-txts.com")
|
||||
test.AssertEquals(t, res.Problem.ProblemType, "unauthorized")
|
||||
test.AssertEquals(t, res.Problem.Detail, "No TXT record found at _acme-challenge.empty-txts.com")
|
||||
|
||||
test.AssertMetricWithLabelsEquals(t, va.metrics.validationLatency, prometheus.Labels{
|
||||
"operation": opChallAndCAA,
|
||||
|
|
|
|||
|
|
@ -91,7 +91,9 @@ type IsCAAValidResponse struct {
|
|||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Problem *proto.ProblemDetails `protobuf:"bytes,1,opt,name=problem,proto3" json:"problem,omitempty"`
|
||||
Problem *proto.ProblemDetails `protobuf:"bytes,1,opt,name=problem,proto3" json:"problem,omitempty"`
|
||||
Perspective string `protobuf:"bytes,3,opt,name=perspective,proto3" json:"perspective,omitempty"`
|
||||
Rir string `protobuf:"bytes,4,opt,name=rir,proto3" json:"rir,omitempty"`
|
||||
}
|
||||
|
||||
func (x *IsCAAValidResponse) Reset() {
|
||||
|
|
@ -133,6 +135,20 @@ func (x *IsCAAValidResponse) GetProblem() *proto.ProblemDetails {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *IsCAAValidResponse) GetPerspective() string {
|
||||
if x != nil {
|
||||
return x.Perspective
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *IsCAAValidResponse) GetRir() string {
|
||||
if x != nil {
|
||||
return x.Rir
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type PerformValidationRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
|
@ -265,7 +281,7 @@ type ValidationResult struct {
|
|||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Records []*proto.ValidationRecord `protobuf:"bytes,1,rep,name=records,proto3" json:"records,omitempty"`
|
||||
Problems *proto.ProblemDetails `protobuf:"bytes,2,opt,name=problems,proto3" json:"problems,omitempty"`
|
||||
Problem *proto.ProblemDetails `protobuf:"bytes,2,opt,name=problem,proto3" json:"problem,omitempty"`
|
||||
Perspective string `protobuf:"bytes,3,opt,name=perspective,proto3" json:"perspective,omitempty"`
|
||||
Rir string `protobuf:"bytes,4,opt,name=rir,proto3" json:"rir,omitempty"`
|
||||
}
|
||||
|
|
@ -309,9 +325,9 @@ func (x *ValidationResult) GetRecords() []*proto.ValidationRecord {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *ValidationResult) GetProblems() *proto.ProblemDetails {
|
||||
func (x *ValidationResult) GetProblem() *proto.ProblemDetails {
|
||||
if x != nil {
|
||||
return x.Problems
|
||||
return x.Problem
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -343,50 +359,53 @@ var file_va_proto_rawDesc = []byte{
|
|||
0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x22,
|
||||
0x0a, 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x52, 0x49, 0x49, 0x44, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x55, 0x52, 0x49,
|
||||
0x49, 0x44, 0x22, 0x44, 0x0a, 0x12, 0x49, 0x73, 0x43, 0x41, 0x41, 0x56, 0x61, 0x6c, 0x69, 0x64,
|
||||
0x49, 0x44, 0x22, 0x78, 0x0a, 0x12, 0x49, 0x73, 0x43, 0x41, 0x41, 0x56, 0x61, 0x6c, 0x69, 0x64,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x62,
|
||||
0x6c, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f, 0x72, 0x65,
|
||||
0x2e, 0x50, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52,
|
||||
0x07, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x22, 0xc4, 0x01, 0x0a, 0x18, 0x50, 0x65, 0x72,
|
||||
0x66, 0x6f, 0x72, 0x6d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x6e, 0x73, 0x4e, 0x61, 0x6d, 0x65,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6e, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x2d, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x43, 0x68, 0x61, 0x6c, 0x6c, 0x65,
|
||||
0x6e, 0x67, 0x65, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x12, 0x23,
|
||||
0x0a, 0x05, 0x61, 0x75, 0x74, 0x68, 0x7a, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e,
|
||||
0x76, 0x61, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x7a, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x05, 0x61, 0x75,
|
||||
0x74, 0x68, 0x7a, 0x12, 0x3a, 0x0a, 0x18, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4b,
|
||||
0x65, 0x79, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4b,
|
||||
0x65, 0x79, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22,
|
||||
0x31, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x7a, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02,
|
||||
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x72, 0x65, 0x67, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x72, 0x65, 0x67,
|
||||
0x49, 0x44, 0x22, 0xaa, 0x01, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x30, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72,
|
||||
0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e,
|
||||
0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64,
|
||||
0x52, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x30, 0x0a, 0x08, 0x70, 0x72, 0x6f,
|
||||
0x62, 0x6c, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x6f,
|
||||
0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c,
|
||||
0x73, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x70,
|
||||
0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0b, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x10, 0x0a,
|
||||
0x03, 0x72, 0x69, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x72, 0x69, 0x72, 0x32,
|
||||
0x4f, 0x0a, 0x02, 0x56, 0x41, 0x12, 0x49, 0x0a, 0x11, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d,
|
||||
0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x76, 0x61, 0x2e,
|
||||
0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x61, 0x2e, 0x56, 0x61,
|
||||
0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00,
|
||||
0x32, 0x44, 0x0a, 0x03, 0x43, 0x41, 0x41, 0x12, 0x3d, 0x0a, 0x0a, 0x49, 0x73, 0x43, 0x41, 0x41,
|
||||
0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x15, 0x2e, 0x76, 0x61, 0x2e, 0x49, 0x73, 0x43, 0x41, 0x41,
|
||||
0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76,
|
||||
0x61, 0x2e, 0x49, 0x73, 0x43, 0x41, 0x41, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x65, 0x74, 0x73, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74,
|
||||
0x2f, 0x62, 0x6f, 0x75, 0x6c, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x07, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x73,
|
||||
0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70,
|
||||
0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x69,
|
||||
0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x72, 0x69, 0x72, 0x22, 0xc4, 0x01, 0x0a,
|
||||
0x18, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x6e, 0x73,
|
||||
0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6e, 0x73, 0x4e,
|
||||
0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x43, 0x68,
|
||||
0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x67, 0x65, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6c, 0x6c, 0x65, 0x6e,
|
||||
0x67, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x61, 0x75, 0x74, 0x68, 0x7a, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x0d, 0x2e, 0x76, 0x61, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x7a, 0x4d, 0x65, 0x74, 0x61,
|
||||
0x52, 0x05, 0x61, 0x75, 0x74, 0x68, 0x7a, 0x12, 0x3a, 0x0a, 0x18, 0x65, 0x78, 0x70, 0x65, 0x63,
|
||||
0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x65, 0x78, 0x70, 0x65, 0x63,
|
||||
0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x22, 0x31, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x7a, 0x4d, 0x65, 0x74, 0x61,
|
||||
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x67, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x05, 0x72, 0x65, 0x67, 0x49, 0x44, 0x22, 0xa8, 0x01, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x30, 0x0a, 0x07, 0x72,
|
||||
0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63,
|
||||
0x6f, 0x72, 0x65, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
|
||||
0x63, 0x6f, 0x72, 0x64, 0x52, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x2e, 0x0a,
|
||||
0x07, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14,
|
||||
0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x44, 0x65, 0x74,
|
||||
0x61, 0x69, 0x6c, 0x73, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x62, 0x6c, 0x65, 0x6d, 0x12, 0x20, 0x0a,
|
||||
0x0b, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12,
|
||||
0x10, 0x0a, 0x03, 0x72, 0x69, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x72, 0x69,
|
||||
0x72, 0x32, 0x4f, 0x0a, 0x02, 0x56, 0x41, 0x12, 0x49, 0x0a, 0x11, 0x50, 0x65, 0x72, 0x66, 0x6f,
|
||||
0x72, 0x6d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x76,
|
||||
0x61, 0x2e, 0x50, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x61, 0x2e,
|
||||
0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74,
|
||||
0x22, 0x00, 0x32, 0x44, 0x0a, 0x03, 0x43, 0x41, 0x41, 0x12, 0x3d, 0x0a, 0x0a, 0x49, 0x73, 0x43,
|
||||
0x41, 0x41, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x15, 0x2e, 0x76, 0x61, 0x2e, 0x49, 0x73, 0x43,
|
||||
0x41, 0x41, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16,
|
||||
0x2e, 0x76, 0x61, 0x2e, 0x49, 0x73, 0x43, 0x41, 0x41, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68,
|
||||
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x65, 0x74, 0x73, 0x65, 0x6e, 0x63, 0x72, 0x79,
|
||||
0x70, 0x74, 0x2f, 0x62, 0x6f, 0x75, 0x6c, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x61, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
@ -417,7 +436,7 @@ var file_va_proto_depIdxs = []int32{
|
|||
6, // 1: va.PerformValidationRequest.challenge:type_name -> core.Challenge
|
||||
3, // 2: va.PerformValidationRequest.authz:type_name -> va.AuthzMeta
|
||||
7, // 3: va.ValidationResult.records:type_name -> core.ValidationRecord
|
||||
5, // 4: va.ValidationResult.problems:type_name -> core.ProblemDetails
|
||||
5, // 4: va.ValidationResult.problem:type_name -> core.ProblemDetails
|
||||
2, // 5: va.VA.PerformValidation:input_type -> va.PerformValidationRequest
|
||||
0, // 6: va.CAA.IsCAAValid:input_type -> va.IsCAAValidRequest
|
||||
4, // 7: va.VA.PerformValidation:output_type -> va.ValidationResult
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ message IsCAAValidRequest {
|
|||
// If CAA is valid for the requested domain, the problem will be empty
|
||||
message IsCAAValidResponse {
|
||||
core.ProblemDetails problem = 1;
|
||||
string perspective = 3;
|
||||
string rir = 4;
|
||||
}
|
||||
|
||||
message PerformValidationRequest {
|
||||
|
|
@ -39,7 +41,7 @@ message AuthzMeta {
|
|||
|
||||
message ValidationResult {
|
||||
repeated core.ValidationRecord records = 1;
|
||||
core.ProblemDetails problems = 2;
|
||||
core.ProblemDetails problem = 2;
|
||||
string perspective = 3;
|
||||
string rir = 4;
|
||||
}
|
||||
|
|
|
|||
71
va/va.go
71
va/va.go
|
|
@ -18,9 +18,11 @@ import (
|
|||
|
||||
"github.com/jmhodges/clock"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/letsencrypt/boulder/bdns"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
corepb "github.com/letsencrypt/boulder/core/proto"
|
||||
berrors "github.com/letsencrypt/boulder/errors"
|
||||
bgrpc "github.com/letsencrypt/boulder/grpc"
|
||||
"github.com/letsencrypt/boulder/identifier"
|
||||
|
|
@ -452,15 +454,35 @@ func (va *ValidationAuthorityImpl) observeLatency(op, perspective, challType, pr
|
|||
va.metrics.validationLatency.With(labels).Observe(latency.Seconds())
|
||||
}
|
||||
|
||||
// performRemoteValidation coordinates the whole process of kicking off and
|
||||
// collecting results from calls to remote VAs' PerformValidation function. It
|
||||
// returns a problem if too many remote perspectives failed to corroborate
|
||||
// domain control, or nil if enough succeeded to surpass our corroboration
|
||||
// threshold.
|
||||
func (va *ValidationAuthorityImpl) performRemoteValidation(
|
||||
ctx context.Context,
|
||||
req *vapb.PerformValidationRequest,
|
||||
) *probs.ProblemDetails {
|
||||
// remoteOperation is a func type that encapsulates the operation and request
|
||||
// passed to va.performRemoteOperation. The operation must be a method on
|
||||
// vapb.VAClient or vapb.CAAClient, and the request must be the corresponding
|
||||
// proto.Message passed to that method.
|
||||
type remoteOperation = func(context.Context, RemoteVA, proto.Message) (remoteResult, error)
|
||||
|
||||
// remoteResult is an interface that must be implemented by the results of a
|
||||
// remoteOperation, such as *vapb.ValidationResult and *vapb.IsCAAValidResponse.
|
||||
// It provides methods to access problem details, the associated perspective,
|
||||
// and the RIR.
|
||||
type remoteResult interface {
|
||||
proto.Message
|
||||
GetProblem() *corepb.ProblemDetails
|
||||
GetPerspective() string
|
||||
GetRir() string
|
||||
}
|
||||
|
||||
var _ remoteResult = (*vapb.ValidationResult)(nil)
|
||||
var _ remoteResult = (*vapb.IsCAAValidResponse)(nil)
|
||||
|
||||
// performRemoteOperation concurrently calls the provided operation with `req` and a
|
||||
// RemoteVA once for each configured RemoteVA. It cancels remaining operations and returns
|
||||
// early if either the required number of successful results is obtained or the number of
|
||||
// failures exceeds va.maxRemoteFailures.
|
||||
//
|
||||
// Internal logic errors are logged. If the number of operation failures exceeds
|
||||
// va.maxRemoteFailures, the first encountered problem is returned as a
|
||||
// *probs.ProblemDetails.
|
||||
func (va *ValidationAuthorityImpl) performRemoteOperation(ctx context.Context, op remoteOperation, req proto.Message) *probs.ProblemDetails {
|
||||
remoteVACount := len(va.remoteVAs)
|
||||
if remoteVACount == 0 {
|
||||
return nil
|
||||
|
|
@ -470,7 +492,7 @@ func (va *ValidationAuthorityImpl) performRemoteValidation(
|
|||
addr string
|
||||
perspective string
|
||||
rir string
|
||||
result *vapb.ValidationResult
|
||||
result remoteResult
|
||||
err error
|
||||
}
|
||||
|
||||
|
|
@ -480,7 +502,7 @@ func (va *ValidationAuthorityImpl) performRemoteValidation(
|
|||
responses := make(chan *response, remoteVACount)
|
||||
for _, i := range rand.Perm(remoteVACount) {
|
||||
go func(rva RemoteVA) {
|
||||
res, err := rva.PerformValidation(subCtx, req)
|
||||
res, err := op(subCtx, rva, req)
|
||||
responses <- &response{rva.Address, rva.Perspective, rva.RIR, res, err}
|
||||
}(va.remoteVAs[i])
|
||||
}
|
||||
|
|
@ -498,20 +520,20 @@ func (va *ValidationAuthorityImpl) performRemoteValidation(
|
|||
failed = append(failed, resp.perspective)
|
||||
|
||||
if core.IsCanceled(resp.err) {
|
||||
currProb = probs.ServerInternal("Secondary domain validation RPC canceled")
|
||||
currProb = probs.ServerInternal("Secondary validation RPC canceled")
|
||||
} else {
|
||||
va.log.Errf("Remote VA %q.PerformValidation failed: %s", resp.addr, resp.err)
|
||||
currProb = probs.ServerInternal("Secondary domain validation RPC failed")
|
||||
va.log.Errf("Operation on remote VA (%s) failed: %s", resp.addr, resp.err)
|
||||
currProb = probs.ServerInternal("Secondary validation RPC failed")
|
||||
}
|
||||
} else if resp.result.Problems != nil {
|
||||
} else if resp.result.GetProblem() != nil {
|
||||
// The remote VA returned a problem.
|
||||
failed = append(failed, resp.perspective)
|
||||
|
||||
var err error
|
||||
currProb, err = bgrpc.PBToProblemDetails(resp.result.Problems)
|
||||
currProb, err = bgrpc.PBToProblemDetails(resp.result.GetProblem())
|
||||
if err != nil {
|
||||
va.log.Errf("Remote VA %q.PerformValidation returned malformed problem: %s", resp.addr, err)
|
||||
currProb = probs.ServerInternal("Secondary domain validation RPC returned malformed result")
|
||||
va.log.Errf("Operation on Remote VA (%s) returned malformed problem: %s", resp.addr, err)
|
||||
currProb = probs.ServerInternal("Secondary validation RPC returned malformed result")
|
||||
}
|
||||
} else {
|
||||
// The remote VA returned a successful result.
|
||||
|
|
@ -542,12 +564,12 @@ func (va *ValidationAuthorityImpl) performRemoteValidation(
|
|||
if len(passed) >= required {
|
||||
return nil
|
||||
} else if len(failed) > va.maxRemoteFailures {
|
||||
firstProb.Detail = fmt.Sprintf("During secondary domain validation: %s", firstProb.Detail)
|
||||
firstProb.Detail = fmt.Sprintf("During secondary validation: %s", firstProb.Detail)
|
||||
return firstProb
|
||||
} else {
|
||||
// This condition should not occur - it indicates the passed/failed counts
|
||||
// neither met the required threshold nor the maxRemoteFailures threshold.
|
||||
return probs.ServerInternal("Too few remote PerformValidation RPC results")
|
||||
return probs.ServerInternal("Too few remote RPC results")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -734,6 +756,13 @@ func (va *ValidationAuthorityImpl) PerformValidation(ctx context.Context, req *v
|
|||
// singular problem, because the remote VAs have already audit-logged their
|
||||
// own validation records, and it's not helpful to present multiple large
|
||||
// errors to the end user.
|
||||
prob = va.performRemoteValidation(ctx, req)
|
||||
op := func(ctx context.Context, remoteva RemoteVA, req proto.Message) (remoteResult, error) {
|
||||
validationRequest, ok := req.(*vapb.PerformValidationRequest)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("got type %T, want *vapb.PerformValidationRequest", req)
|
||||
}
|
||||
return remoteva.PerformValidation(ctx, validationRequest)
|
||||
}
|
||||
prob = va.performRemoteOperation(ctx, op, req)
|
||||
return bgrpc.ValidationResultToPB(records, filterProblemDetails(prob), va.perspective, va.rir)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"github.com/jmhodges/clock"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/letsencrypt/boulder/bdns"
|
||||
"github.com/letsencrypt/boulder/core"
|
||||
|
|
@ -346,7 +347,7 @@ func TestPerformValidationInvalid(t *testing.T) {
|
|||
|
||||
req := createValidationRequest("foo.com", core.ChallengeTypeDNS01)
|
||||
res, _ := va.PerformValidation(context.Background(), req)
|
||||
test.Assert(t, res.Problems != nil, "validation succeeded")
|
||||
test.Assert(t, res.Problem != nil, "validation succeeded")
|
||||
test.AssertMetricWithLabelsEquals(t, va.metrics.validationLatency, prometheus.Labels{
|
||||
"operation": opChallAndCAA,
|
||||
"perspective": va.perspective,
|
||||
|
|
@ -375,7 +376,7 @@ func TestPerformValidationValid(t *testing.T) {
|
|||
// create a challenge with well known token
|
||||
req := createValidationRequest("good-dns01.com", core.ChallengeTypeDNS01)
|
||||
res, _ := va.PerformValidation(context.Background(), req)
|
||||
test.Assert(t, res.Problems == nil, fmt.Sprintf("validation failed: %#v", res.Problems))
|
||||
test.Assert(t, res.Problem == nil, fmt.Sprintf("validation failed: %#v", res.Problem))
|
||||
|
||||
test.AssertMetricWithLabelsEquals(t, va.metrics.validationLatency, prometheus.Labels{
|
||||
"operation": opChallAndCAA,
|
||||
|
|
@ -402,7 +403,7 @@ func TestPerformValidationWildcard(t *testing.T) {
|
|||
req := createValidationRequest("*.good-dns01.com", core.ChallengeTypeDNS01)
|
||||
// perform a validation for a wildcard name
|
||||
res, _ := va.PerformValidation(context.Background(), req)
|
||||
test.Assert(t, res.Problems == nil, fmt.Sprintf("validation failed: %#v", res.Problems))
|
||||
test.Assert(t, res.Problem == nil, fmt.Sprintf("validation failed: %#v", res.Problem))
|
||||
|
||||
test.AssertMetricWithLabelsEquals(t, va.metrics.validationLatency, prometheus.Labels{
|
||||
"operation": opChallAndCAA,
|
||||
|
|
@ -435,7 +436,7 @@ func TestDCVAndCAASequencing(t *testing.T) {
|
|||
req := createValidationRequest("good-dns01.com", core.ChallengeTypeDNS01)
|
||||
res, err := va.PerformValidation(context.Background(), req)
|
||||
test.AssertNotError(t, err, "performing validation")
|
||||
test.Assert(t, res.Problems == nil, fmt.Sprintf("validation failed: %#v", res.Problems))
|
||||
test.Assert(t, res.Problem == nil, fmt.Sprintf("validation failed: %#v", res.Problem))
|
||||
caaLog := mockLog.GetAllMatching(`Checked CAA records for`)
|
||||
test.AssertEquals(t, len(caaLog), 1)
|
||||
|
||||
|
|
@ -444,11 +445,75 @@ func TestDCVAndCAASequencing(t *testing.T) {
|
|||
req = createValidationRequest("bad-dns01.com", core.ChallengeTypeDNS01)
|
||||
res, err = va.PerformValidation(context.Background(), req)
|
||||
test.AssertNotError(t, err, "performing validation")
|
||||
test.Assert(t, res.Problems != nil, "validation succeeded")
|
||||
test.Assert(t, res.Problem != nil, "validation succeeded")
|
||||
caaLog = mockLog.GetAllMatching(`Checked CAA records for`)
|
||||
test.AssertEquals(t, len(caaLog), 0)
|
||||
}
|
||||
|
||||
func TestPerformRemoteOperation(t *testing.T) {
|
||||
va, _ := setupWithRemotes(nil, "", []remoteConf{
|
||||
{ua: pass, rir: arin},
|
||||
{ua: pass, rir: ripe},
|
||||
{ua: pass, rir: apnic},
|
||||
}, nil)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
req proto.Message
|
||||
expectedType string
|
||||
expectedDetail string
|
||||
op func(ctx context.Context, rva RemoteVA, req proto.Message) (remoteResult, error)
|
||||
}{
|
||||
{
|
||||
name: "ValidationResult",
|
||||
req: &vapb.PerformValidationRequest{},
|
||||
expectedType: string(probs.BadNonceProblem),
|
||||
expectedDetail: "quite surprising",
|
||||
op: func(ctx context.Context, rva RemoteVA, req proto.Message) (remoteResult, error) {
|
||||
prob := &corepb.ProblemDetails{
|
||||
ProblemType: string(probs.BadNonceProblem),
|
||||
Detail: "quite surprising",
|
||||
}
|
||||
return &vapb.ValidationResult{Problem: prob, Perspective: rva.Perspective, Rir: rva.RIR}, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "IsCAAValidResponse",
|
||||
req: &vapb.IsCAAValidRequest{},
|
||||
expectedType: string(probs.PausedProblem),
|
||||
expectedDetail: "quite surprising, indeed",
|
||||
op: func(ctx context.Context, rva RemoteVA, req proto.Message) (remoteResult, error) {
|
||||
prob := &corepb.ProblemDetails{
|
||||
ProblemType: string(probs.PausedProblem),
|
||||
Detail: "quite surprising, indeed",
|
||||
}
|
||||
return &vapb.IsCAAValidResponse{Problem: prob, Perspective: rva.Perspective, Rir: rva.RIR}, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "IsCAAValidRequestWithValidationResult",
|
||||
req: &vapb.IsCAAValidRequest{},
|
||||
expectedType: string(probs.BadPublicKeyProblem),
|
||||
expectedDetail: "a shocking result",
|
||||
op: func(ctx context.Context, rva RemoteVA, req proto.Message) (remoteResult, error) {
|
||||
prob := &corepb.ProblemDetails{
|
||||
ProblemType: string(probs.BadPublicKeyProblem),
|
||||
Detail: "a shocking result",
|
||||
}
|
||||
return &vapb.ValidationResult{Problem: prob, Perspective: rva.Perspective, Rir: rva.RIR}, nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
prob := va.performRemoteOperation(context.Background(), tc.op, tc.req)
|
||||
test.AssertEquals(t, string(prob.Type), tc.expectedType)
|
||||
test.AssertContains(t, prob.Detail, tc.expectedDetail)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiVA(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
|
@ -581,7 +646,7 @@ func TestMultiVA(t *testing.T) {
|
|||
},
|
||||
PrimaryUA: pass,
|
||||
ExpectedProbType: string(probs.UnauthorizedProblem),
|
||||
ExpectedLogContains: "During secondary domain validation: The key authorization file from the server",
|
||||
ExpectedLogContains: "During secondary validation: The key authorization file from the server",
|
||||
},
|
||||
{
|
||||
// If one remote VA cancels, it should succeed
|
||||
|
|
@ -603,7 +668,7 @@ func TestMultiVA(t *testing.T) {
|
|||
},
|
||||
PrimaryUA: pass,
|
||||
ExpectedProbType: string(probs.ServerInternalProblem),
|
||||
ExpectedLogContains: "During secondary domain validation: Secondary domain validation RPC canceled",
|
||||
ExpectedLogContains: "During secondary validation: Secondary validation RPC canceled",
|
||||
},
|
||||
{
|
||||
// With the local and remote VAs seeing diff problems, we expect a problem.
|
||||
|
|
@ -615,7 +680,7 @@ func TestMultiVA(t *testing.T) {
|
|||
},
|
||||
PrimaryUA: pass,
|
||||
ExpectedProbType: string(probs.UnauthorizedProblem),
|
||||
ExpectedLogContains: "During secondary domain validation: The key authorization file from the server",
|
||||
ExpectedLogContains: "During secondary validation: The key authorization file from the server",
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -632,13 +697,13 @@ func TestMultiVA(t *testing.T) {
|
|||
|
||||
// Perform all validations
|
||||
res, _ := localVA.PerformValidation(ctx, req)
|
||||
if res.Problems == nil && tc.ExpectedProbType != "" {
|
||||
if res.Problem == nil && tc.ExpectedProbType != "" {
|
||||
t.Errorf("expected prob %v, got nil", tc.ExpectedProbType)
|
||||
} else if res.Problems != nil && tc.ExpectedProbType == "" {
|
||||
t.Errorf("expected no prob, got %v", res.Problems)
|
||||
} else if res.Problems != nil && tc.ExpectedProbType != "" {
|
||||
} else if res.Problem != nil && tc.ExpectedProbType == "" {
|
||||
t.Errorf("expected no prob, got %v", res.Problem)
|
||||
} else if res.Problem != nil && tc.ExpectedProbType != "" {
|
||||
// That result should match expected.
|
||||
test.AssertEquals(t, res.Problems.ProblemType, tc.ExpectedProbType)
|
||||
test.AssertEquals(t, res.Problem.ProblemType, tc.ExpectedProbType)
|
||||
}
|
||||
|
||||
if tc.ExpectedLogContains != "" {
|
||||
|
|
@ -701,7 +766,7 @@ func TestMultiVAEarlyReturn(t *testing.T) {
|
|||
res, _ := localVA.PerformValidation(ctx, req)
|
||||
|
||||
// It should always fail
|
||||
if res.Problems == nil {
|
||||
if res.Problem == nil {
|
||||
t.Error("expected prob from PerformValidation, got nil")
|
||||
}
|
||||
|
||||
|
|
@ -739,7 +804,7 @@ func TestMultiVAPolicy(t *testing.T) {
|
|||
req := createValidationRequest("letsencrypt.org", core.ChallengeTypeHTTP01)
|
||||
res, _ := localVA.PerformValidation(ctx, req)
|
||||
// It should fail
|
||||
if res.Problems == nil {
|
||||
if res.Problem == nil {
|
||||
t.Error("expected prob from PerformValidation, got nil")
|
||||
}
|
||||
}
|
||||
|
|
@ -758,7 +823,7 @@ func TestMultiVALogging(t *testing.T) {
|
|||
va, _ := setupWithRemotes(ms.Server, pass, remoteConfs, nil)
|
||||
req := createValidationRequest("letsencrypt.org", core.ChallengeTypeHTTP01)
|
||||
res, err := va.PerformValidation(ctx, req)
|
||||
test.Assert(t, res.Problems == nil, fmt.Sprintf("validation failed with: %#v", res.Problems))
|
||||
test.Assert(t, res.Problem == nil, fmt.Sprintf("validation failed with: %#v", res.Problem))
|
||||
test.AssertNotError(t, err, "performing validation")
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue