github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/credentials/tls/certprovider/pemfile/builder.go (about) 1 /* 2 * 3 * Copyright 2020 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package pemfile 20 21 import ( 22 "encoding/json" 23 "fmt" 24 "time" 25 26 "github.com/hxx258456/ccgo/grpc/credentials/tls/certprovider" 27 "google.golang.org/protobuf/encoding/protojson" 28 "google.golang.org/protobuf/types/known/durationpb" 29 ) 30 31 const ( 32 pluginName = "file_watcher" 33 defaultRefreshInterval = 10 * time.Minute 34 ) 35 36 func init() { 37 certprovider.Register(&pluginBuilder{}) 38 } 39 40 type pluginBuilder struct{} 41 42 func (p *pluginBuilder) ParseConfig(c interface{}) (*certprovider.BuildableConfig, error) { 43 data, ok := c.(json.RawMessage) 44 if !ok { 45 return nil, fmt.Errorf("meshca: unsupported config type: %T", c) 46 } 47 opts, err := pluginConfigFromJSON(data) 48 if err != nil { 49 return nil, err 50 } 51 return certprovider.NewBuildableConfig(pluginName, opts.canonical(), func(certprovider.BuildOptions) certprovider.Provider { 52 return newProvider(opts) 53 }), nil 54 } 55 56 func (p *pluginBuilder) Name() string { 57 return pluginName 58 } 59 60 func pluginConfigFromJSON(jd json.RawMessage) (Options, error) { 61 // The only difference between this anonymous struct and the Options struct 62 // is that the refresh_interval is represented here as a duration proto, 63 // while in the latter a time.Duration is used. 64 cfg := &struct { 65 CertificateFile string `json:"certificate_file,omitempty"` 66 PrivateKeyFile string `json:"private_key_file,omitempty"` 67 CACertificateFile string `json:"ca_certificate_file,omitempty"` 68 RefreshInterval json.RawMessage `json:"refresh_interval,omitempty"` 69 }{} 70 if err := json.Unmarshal(jd, cfg); err != nil { 71 return Options{}, fmt.Errorf("pemfile: json.Unmarshal(%s) failed: %v", string(jd), err) 72 } 73 74 opts := Options{ 75 CertFile: cfg.CertificateFile, 76 KeyFile: cfg.PrivateKeyFile, 77 RootFile: cfg.CACertificateFile, 78 // Refresh interval is the only field in the configuration for which we 79 // support a default value. We cannot possibly have valid defaults for 80 // file paths to watch. Also, it is valid to specify an empty path for 81 // some of those fields if the user does not want to watch them. 82 RefreshDuration: defaultRefreshInterval, 83 } 84 if cfg.RefreshInterval != nil { 85 dur := &durationpb.Duration{} 86 if err := protojson.Unmarshal(cfg.RefreshInterval, dur); err != nil { 87 return Options{}, fmt.Errorf("pemfile: protojson.Unmarshal(%+v) failed: %v", cfg.RefreshInterval, err) 88 } 89 opts.RefreshDuration = dur.AsDuration() 90 } 91 92 if err := opts.validate(); err != nil { 93 return Options{}, err 94 } 95 return opts, nil 96 }