diff --git a/cas/apiv1/options.go b/cas/apiv1/options.go index 80d42d90..412cc654 100644 --- a/cas/apiv1/options.go +++ b/cas/apiv1/options.go @@ -45,11 +45,15 @@ type Options struct { // KeyManager is the KMS used to generate keys in SoftCAS. KeyManager kms.KeyManager `json:"-"` - // Project and Location are parameters used in CloudCAS to create a new - // certificate authority. - Project string `json:"-"` - Location string `json:"-"` - CaPool string `json:"-"` + // Project, Location, CaPool and GCSBucket are parameters used in CloudCAS + // to create a new certificate authority. If a CaPool does not exists it + // will be created. GCSBucket is optional, if not provided GCloud will + // create a managed bucket. + Project string `json:"-"` + Location string `json:"-"` + CaPool string `json:"-"` + CaPoolTier string `json:"-"` + GCSBucket string `json:"-"` } // CertificateIssuer contains the properties used to use the StepCAS certificate diff --git a/cas/cloudcas/cloudcas.go b/cas/cloudcas/cloudcas.go index a4e1552c..b5fb309c 100644 --- a/cas/cloudcas/cloudcas.go +++ b/cas/cloudcas/cloudcas.go @@ -5,6 +5,7 @@ import ( "crypto/rand" "crypto/x509" "encoding/asn1" + "encoding/json" "encoding/pem" "regexp" "strings" @@ -67,6 +68,13 @@ var revocationCodeMap = map[int]pb.RevocationReason{ 10: pb.RevocationReason_ATTRIBUTE_AUTHORITY_COMPROMISE, } +// caPoolTierMap contains the map between apv1.Options.Tier and the pb type. +var caPoolTierMap = map[string]pb.CaPool_Tier{ + "": pb.CaPool_DEVOPS, + "ENTERPRISE": pb.CaPool_ENTERPRISE, + "DEVOPS": pb.CaPool_DEVOPS, +} + // CloudCAS implements a Certificate Authority Service using Google Cloud CAS. type CloudCAS struct { client CertificateAuthorityClient @@ -74,6 +82,7 @@ type CloudCAS struct { project string location string caPool string + caPoolTier pb.CaPool_Tier gcsBucket string } @@ -94,7 +103,8 @@ var newCertificateAuthorityClient = func(ctx context.Context, credentialsFile st // New creates a new CertificateAuthorityService implementation using Google // Cloud CAS. func New(ctx context.Context, opts apiv1.Options) (*CloudCAS, error) { - if opts.IsCreator { + var caPoolTier pb.CaPool_Tier + if opts.IsCreator && opts.CertificateAuthority == "" { switch { case opts.Project == "": return nil, errors.New("cloudCAS 'project' cannot be empty") @@ -103,7 +113,10 @@ func New(ctx context.Context, opts apiv1.Options) (*CloudCAS, error) { case opts.CaPool == "": return nil, errors.New("cloudCAS 'caPool' cannot be empty") } - + var ok bool + if caPoolTier, ok = caPoolTierMap[strings.ToUpper(opts.CaPoolTier)]; !ok { + return nil, errors.New("cloudCAS 'caPoolTier' is not a valid tier") + } } else { if opts.CertificateAuthority == "" { return nil, errors.New("cloudCAS 'certificateAuthority' cannot be empty") @@ -130,12 +143,15 @@ func New(ctx context.Context, opts apiv1.Options) (*CloudCAS, error) { return nil, err } + // GCSBucket is the the bucket name or empty for a managed bucket. return &CloudCAS{ client: client, certificateAuthority: opts.CertificateAuthority, project: opts.Project, location: opts.Location, caPool: opts.CaPool, + gcsBucket: opts.GCSBucket, + caPoolTier: caPoolTier, }, nil } @@ -267,6 +283,8 @@ func (c *CloudCAS) CreateCertificateAuthority(req *apiv1.CreateCertificateAuthor return nil, errors.New("cloudCAS `location` cannot be empty") case c.caPool == "": return nil, errors.New("cloudCAS `caPool` cannot be empty") + case c.caPoolTier == 0: + return nil, errors.New("cloudCAS `caPoolTier` cannot be empty") case req.Template == nil: return nil, errors.New("createCertificateAuthorityRequest `template` cannot be nil") case req.Lifetime == 0: @@ -362,14 +380,6 @@ func (c *CloudCAS) CreateCertificateAuthority(req *apiv1.CreateCertificateAuthor return nil, errors.Wrap(err, "cloudCAS CreateCertificateAuthority failed") } - // Enable root certificate - if req.Type == apiv1.RootCA { - ca, err = c.enableCertificateAuthority(ca) - if err != nil { - return nil, err - } - } - // Sign Intermediate CAs with the parent. if req.Type == apiv1.IntermediateCA { ca, err = c.signIntermediateCA(parent, ca.Name, req) @@ -378,6 +388,12 @@ func (c *CloudCAS) CreateCertificateAuthority(req *apiv1.CreateCertificateAuthor } } + // Enable Certificate Authority. + ca, err = c.enableCertificateAuthority(ca) + if err != nil { + return nil, err + } + if len(ca.PemCaCertificates) == 0 { return nil, errors.New("cloudCAS CreateCertificateAuthority failed: PemCaCertificates is empty") } @@ -397,6 +413,9 @@ func (c *CloudCAS) CreateCertificateAuthority(req *apiv1.CreateCertificateAuthor } } + b, _ := json.MarshalIndent(ca, "", "\t") + println(string(b)) + return &apiv1.CreateCertificateAuthorityResponse{ Name: ca.Name, Certificate: cert, @@ -419,6 +438,12 @@ func (c *CloudCAS) createCaPoolIfNecessary() (string, error) { return "", errors.Wrap(err, "cloudCAS GetCaPool failed") } + // PublishCrl is only supported by the enterprise tier + var publishCrl bool + if c.caPoolTier == pb.CaPool_ENTERPRISE { + publishCrl = true + } + ctx, cancel = defaultContext() defer cancel() @@ -426,11 +451,11 @@ func (c *CloudCAS) createCaPoolIfNecessary() (string, error) { Parent: "projects/" + c.project + "/locations/" + c.location, CaPoolId: c.caPool, CaPool: &pb.CaPool{ - Tier: pb.CaPool_ENTERPRISE, + Tier: c.caPoolTier, IssuancePolicy: nil, PublishingOptions: &pb.CaPool_PublishingOptions{ PublishCaCert: true, - PublishCrl: true, + PublishCrl: publishCrl, }, }, }) @@ -507,7 +532,8 @@ func (c *CloudCAS) createCertificate(tpl *x509.Certificate, lifetime time.Durati Lifetime: durationpb.New(lifetime), Labels: map[string]string{}, }, - RequestId: requestID, + IssuingCertificateAuthorityId: getResourceName(c.certificateAuthority), + RequestId: requestID, }) if err != nil { return nil, nil, errors.Wrap(err, "cloudCAS CreateCertificate failed") @@ -583,7 +609,8 @@ func (c *CloudCAS) signIntermediateCA(parent, name string, req *apiv1.CreateCert Lifetime: durationpb.New(req.Lifetime), Labels: map[string]string{}, }, - RequestId: req.RequestID, + IssuingCertificateAuthorityId: getResourceName(req.Parent.Name), + RequestId: req.RequestID, }) if err != nil { return nil, errors.Wrap(err, "cloudCAS CreateCertificate failed") @@ -618,12 +645,6 @@ func (c *CloudCAS) signIntermediateCA(parent, name string, req *apiv1.CreateCert return nil, errors.Wrap(err, "cloudCAS ActivateCertificateAuthority failed") } - // Enable certificate authority - ca, err = c.enableCertificateAuthority(ca) - if err != nil { - return nil, err - } - return ca, nil } @@ -690,7 +711,12 @@ func getCertificateAndChain(certpb *pb.Certificate) (*x509.Certificate, []*x509. } return cert, chain, nil +} +// getResourceName returns the last part of a resource. +func getResourceName(name string) string { + parts := strings.Split(name, "/") + return parts[len(parts)-1] } // Normalize a certificate authority name to comply with [a-zA-Z0-9-_]. diff --git a/cas/cloudcas/cloudcas_test.go b/cas/cloudcas/cloudcas_test.go index 6fb5e520..0561000c 100644 --- a/cas/cloudcas/cloudcas_test.go +++ b/cas/cloudcas/cloudcas_test.go @@ -279,6 +279,17 @@ func TestNew(t *testing.T) { project: testProject, location: testLocation, caPool: testCaPool, + caPoolTier: 0, + }, false}, + {"ok authority and creator", args{context.Background(), apiv1.Options{ + CertificateAuthority: testAuthorityName, IsCreator: true, + }}, &CloudCAS{ + client: &testClient{}, + certificateAuthority: testAuthorityName, + project: testProject, + location: testLocation, + caPool: testCaPool, + caPoolTier: 0, }, false}, {"ok with credentials", args{context.Background(), apiv1.Options{ CertificateAuthority: testAuthorityName, CredentialsFile: "testdata/credentials.json", @@ -288,14 +299,34 @@ func TestNew(t *testing.T) { project: testProject, location: testLocation, caPool: testCaPool, + caPoolTier: 0, }, false}, {"ok creator", args{context.Background(), apiv1.Options{ IsCreator: true, Project: testProject, Location: testLocation, CaPool: testCaPool, }}, &CloudCAS{ - client: &testClient{}, - project: testProject, - location: testLocation, - caPool: testCaPool, + client: &testClient{}, + project: testProject, + location: testLocation, + caPool: testCaPool, + caPoolTier: pb.CaPool_DEVOPS, + }, false}, + {"ok creator devops", args{context.Background(), apiv1.Options{ + IsCreator: true, Project: testProject, Location: testLocation, CaPool: testCaPool, CaPoolTier: "DevOps", + }}, &CloudCAS{ + client: &testClient{}, + project: testProject, + location: testLocation, + caPool: testCaPool, + caPoolTier: pb.CaPool_DEVOPS, + }, false}, + {"ok creator enterprise", args{context.Background(), apiv1.Options{ + IsCreator: true, Project: testProject, Location: testLocation, CaPool: testCaPool, CaPoolTier: "ENTERPRISE", + }}, &CloudCAS{ + client: &testClient{}, + project: testProject, + location: testLocation, + caPool: testCaPool, + caPoolTier: pb.CaPool_ENTERPRISE, }, false}, {"fail certificate authority", args{context.Background(), apiv1.Options{ CertificateAuthority: "projects/ok1234/locations/ok1234/caPools/ok1234/certificateAuthorities/ok1234/bad", @@ -1215,6 +1246,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { project string location string caPool string + caPoolTier pb.CaPool_Tier } type args struct { req *apiv1.CreateCertificateAuthorityRequest @@ -1226,7 +1258,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { want *apiv1.CreateCertificateAuthorityResponse wantErr bool }{ - {"ok root", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"ok root", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_ENTERPRISE}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, @@ -1234,7 +1266,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { Name: testAuthorityName, Certificate: rootCrt, }, false}, - {"ok intermediate", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"ok intermediate", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.IntermediateCA, Template: mustParseCertificate(t, testIntermediateCertificate), Lifetime: 24 * time.Hour, @@ -1247,7 +1279,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { Certificate: intCrt, CertificateChain: []*x509.Certificate{rootCrt}, }, false}, - {"ok intermediate local signer", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"ok intermediate local signer", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_ENTERPRISE}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.IntermediateCA, Template: mustParseCertificate(t, testIntermediateCertificate), Lifetime: 24 * time.Hour, @@ -1260,7 +1292,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { Certificate: intCrt, CertificateChain: []*x509.Certificate{rootCrt}, }, false}, - {"ok create key", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"ok create key", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, @@ -1271,46 +1303,46 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { Name: testAuthorityName, Certificate: rootCrt, }, false}, - {"fail project", fields{m, "", "", testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail project", fields{m, "", "", testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, }}, nil, true}, - {"fail location", fields{m, "", testProject, "", testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail location", fields{m, "", testProject, "", testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, }}, nil, true}, - {"fail caPool", fields{m, "", testProject, testLocation, ""}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail caPool", fields{m, "", testProject, testLocation, "", pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, }}, nil, true}, - {"fail template", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail template", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Lifetime: 24 * time.Hour, }}, nil, true}, - {"fail lifetime", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail lifetime", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Template: mustParseCertificate(t, testRootCertificate), }}, nil, true}, - {"fail parent", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail parent", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.IntermediateCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, }}, nil, true}, - {"fail parent name", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail parent name", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.IntermediateCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, Parent: &apiv1.CreateCertificateAuthorityResponse{}, }}, nil, true}, - {"fail type", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail type", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: 0, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, }}, nil, true}, - {"fail create key", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail create key", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, @@ -1318,43 +1350,43 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { SignatureAlgorithm: kmsapi.PureEd25519, }, }}, nil, true}, - {"fail GetCaPool", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail GetCaPool", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, }}, nil, true}, - {"fail CreateCaPool", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail CreateCaPool", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, }}, nil, true}, - {"fail CreateCaPool.Wait", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail CreateCaPool.Wait", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, }}, nil, true}, - {"fail CreateCertificateAuthority", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail CreateCertificateAuthority", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, }}, nil, true}, - {"fail CreateCertificateAuthority.Wait", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail CreateCertificateAuthority.Wait", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, }}, nil, true}, - {"fail EnableCertificateAuthority", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail EnableCertificateAuthority", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, }}, nil, true}, - {"fail EnableCertificateAuthority.Wait", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail EnableCertificateAuthority.Wait", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.RootCA, Template: mustParseCertificate(t, testRootCertificate), Lifetime: 24 * time.Hour, }}, nil, true}, - {"fail EnableCertificateAuthority intermediate", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail EnableCertificateAuthority intermediate", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.IntermediateCA, Template: mustParseCertificate(t, testIntermediateCertificate), Lifetime: 24 * time.Hour, @@ -1363,7 +1395,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { Certificate: rootCrt, }, }}, nil, true}, - {"fail EnableCertificateAuthority.Wait intermediate", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail EnableCertificateAuthority.Wait intermediate", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.IntermediateCA, Template: mustParseCertificate(t, testIntermediateCertificate), Lifetime: 24 * time.Hour, @@ -1373,7 +1405,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { }, }}, nil, true}, - {"fail FetchCertificateAuthorityCsr", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail FetchCertificateAuthorityCsr", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.IntermediateCA, Template: mustParseCertificate(t, testIntermediateCertificate), Lifetime: 24 * time.Hour, @@ -1382,7 +1414,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { Certificate: rootCrt, }, }}, nil, true}, - {"fail CreateCertificate", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail CreateCertificate", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.IntermediateCA, Template: mustParseCertificate(t, testIntermediateCertificate), Lifetime: 24 * time.Hour, @@ -1391,7 +1423,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { Certificate: rootCrt, }, }}, nil, true}, - {"fail ActivateCertificateAuthority", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail ActivateCertificateAuthority", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.IntermediateCA, Template: mustParseCertificate(t, testIntermediateCertificate), Lifetime: 24 * time.Hour, @@ -1400,7 +1432,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { Certificate: rootCrt, }, }}, nil, true}, - {"fail ActivateCertificateAuthority.Wait", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail ActivateCertificateAuthority.Wait", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.IntermediateCA, Template: mustParseCertificate(t, testIntermediateCertificate), Lifetime: 24 * time.Hour, @@ -1409,7 +1441,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { Certificate: rootCrt, }, }}, nil, true}, - {"fail x509util.CreateCertificate", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail x509util.CreateCertificate", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.IntermediateCA, Template: mustParseCertificate(t, testIntermediateCertificate), Lifetime: 24 * time.Hour, @@ -1418,7 +1450,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { Signer: createBadSigner(t), }, }}, nil, true}, - {"fail parseCertificateRequest", fields{m, "", testProject, testLocation, testCaPool}, args{&apiv1.CreateCertificateAuthorityRequest{ + {"fail parseCertificateRequest", fields{m, "", testProject, testLocation, testCaPool, pb.CaPool_DEVOPS}, args{&apiv1.CreateCertificateAuthorityRequest{ Type: apiv1.IntermediateCA, Template: mustParseCertificate(t, testIntermediateCertificate), Lifetime: 24 * time.Hour, @@ -1436,6 +1468,7 @@ func TestCloudCAS_CreateCertificateAuthority(t *testing.T) { project: tt.fields.project, location: tt.fields.location, caPool: tt.fields.caPool, + caPoolTier: tt.fields.caPoolTier, } got, err := c.CreateCertificateAuthority(tt.args.req) if (err != nil) != tt.wantErr {