istio

Форк
0
172 строки · 4.8 Кб
1
// Copyright Istio Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
package mock
16

17
import (
18
	"context"
19
	"errors"
20
	"net"
21
	"path"
22
	"strings"
23
	"time"
24

25
	privatecapb "cloud.google.com/go/security/privateca/apiv1/privatecapb"
26
	"google.golang.org/grpc"
27
	"google.golang.org/grpc/codes"
28
	"google.golang.org/grpc/status"
29
	"google.golang.org/grpc/test/bufconn"
30
)
31

32
const (
33
	bufSize = 1024 * 1024
34
)
35

36
var lis *bufconn.Listener
37

38
type ContextDialer func(ctx context.Context, address string) (net.Conn, error)
39

40
func ContextDialerCreate(listener *bufconn.Listener) ContextDialer {
41
	bufDialer := func(ctx context.Context, address string) (net.Conn, error) {
42
		return listener.Dial()
43
	}
44
	return bufDialer
45
}
46

47
type certificate struct {
48
	resourcePath string
49
	certPEM      string
50
	certChainPEM []string
51
}
52

53
// CASService is a mock Google CAS Service.
54
type CASService struct {
55
	privatecapb.UnimplementedCertificateAuthorityServiceServer
56
	CertPEM      string
57
	CertChainPEM []string
58
	CaCertBundle [][]string
59
}
60

61
func parseCertificateAuthorityPath(p string) (project, location, name string, err error) {
62
	pieces := strings.Split(p, "/")
63
	if len(pieces) != 6 {
64
		return "", "", "", errors.New("malformed certificate authority path")
65
	}
66
	if pieces[0] != "projects" {
67
		return "", "", "", errors.New("malformed certificate authority path")
68
	}
69
	project = pieces[1]
70
	if pieces[2] != "locations" {
71
		return "", "", "", errors.New("malformed certificate authority path")
72
	}
73
	location = pieces[3]
74
	if pieces[4] != "caPools" {
75
		return "", "", "", errors.New("malformed certificate authority path")
76
	}
77
	name = pieces[5]
78
	return project, location, name, nil
79
}
80

81
func (ca CASService) certEncode(cert *certificate) *privatecapb.Certificate {
82
	pb := &privatecapb.Certificate{
83
		Name: cert.resourcePath,
84
	}
85
	if len(cert.certPEM) != 0 {
86
		pb.PemCertificate = cert.certPEM
87
	}
88
	if len(cert.certChainPEM) != 0 {
89
		pb.PemCertificateChain = cert.certChainPEM
90
	}
91
	return pb
92
}
93

94
// CreateCertificate is a mocked function for the Google CAS CA API.
95
func (ca CASService) CreateCertificate(ctx context.Context, req *privatecapb.CreateCertificateRequest) (*privatecapb.Certificate, error) {
96
	_, _, _, err := parseCertificateAuthorityPath(req.Parent)
97
	if err != nil {
98
		return nil, status.Error(codes.InvalidArgument, "malformed ca path")
99
	}
100
	project, location, authority, _ := parseCertificateAuthorityPath(req.GetParent())
101
	switch req.GetCertificate().CertificateConfig.(type) {
102
	case *privatecapb.Certificate_PemCsr:
103
		return nil, status.Errorf(codes.InvalidArgument, "cannot request certificates using PEM CSR format")
104
	}
105
	certResourcePath := path.Join("projects", project, "locations", location, "caPools", authority, "certificates", req.GetCertificate().GetName())
106
	certObj := &certificate{
107
		resourcePath: certResourcePath,
108
		certPEM:      ca.CertPEM,
109
		certChainPEM: ca.CertChainPEM,
110
	}
111
	return ca.certEncode(certObj), nil
112
}
113

114
func (ca CASService) FetchCaCerts(ctx context.Context, req *privatecapb.FetchCaCertsRequest) (*privatecapb.FetchCaCertsResponse, error) {
115
	_, _, _, err := parseCertificateAuthorityPath(req.GetCaPool())
116
	if err != nil {
117
		return nil, status.Error(codes.InvalidArgument, "malformed ca path")
118
	}
119
	certChains := []*privatecapb.FetchCaCertsResponse_CertChain{}
120
	for _, trustBundle := range ca.CaCertBundle {
121
		certChain := &privatecapb.FetchCaCertsResponse_CertChain{}
122
		certChain.Certificates = trustBundle
123
		certChains = append(certChains, certChain)
124
	}
125
	resp := &privatecapb.FetchCaCertsResponse{
126
		CaCerts: certChains,
127
	}
128
	return resp, nil
129
}
130

131
// CASServer is the mocked Google CAS server.
132
type CASServer struct {
133
	Server  *grpc.Server
134
	Address string
135
}
136

137
// CreateServer creates a mocked local Google CAS server and runs it in a separate goroutine.
138
func CreateServer(service *CASService) (*CASServer, *bufconn.Listener, error) {
139
	var err error
140
	s := &CASServer{
141
		Server: grpc.NewServer(),
142
	}
143

144
	lis = bufconn.Listen(bufSize)
145
	serveErr := make(chan error, 1)
146

147
	go func() {
148
		privatecapb.RegisterCertificateAuthorityServiceServer(s.Server, service)
149
		err := s.Server.Serve(lis)
150
		serveErr <- err
151
		close(serveErr)
152
	}()
153

154
	select {
155
	case <-time.After(100 * time.Millisecond):
156
		err = nil
157
	case err = <-serveErr:
158
	}
159

160
	if err != nil {
161
		return nil, nil, err
162
	}
163

164
	return s, lis, nil
165
}
166

167
// Stop stops the Mock Mesh CA server.
168
func (s *CASServer) Stop() {
169
	if s.Server != nil {
170
		s.Server.Stop()
171
	}
172
}
173

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.