github.com/polarismesh/polaris@v1.17.8/plugin/crypto.go (about)

     1  /**
     2   * Tencent is pleased to support the open source community by making Polaris available.
     3   *
     4   * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
     5   *
     6   * Licensed under the BSD 3-Clause License (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   * https://opensource.org/licenses/BSD-3-Clause
    11   *
    12   * Unless required by applicable law or agreed to in writing, software distributed
    13   * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    14   * CONDITIONS OF ANY KIND, either express or implied. See the License for the
    15   * specific language governing permissions and limitations under the License.
    16   */
    17  
    18  package plugin
    19  
    20  import (
    21  	"fmt"
    22  	"os"
    23  	"sync"
    24  )
    25  
    26  var (
    27  	cryptoManagerOnce sync.Once
    28  	cryptoManager     *defaultCryptoManager
    29  )
    30  
    31  // Crypto Crypto interface
    32  type Crypto interface {
    33  	Plugin
    34  	GenerateKey() ([]byte, error)
    35  	Encrypt(plaintext string, key []byte) (cryptotext string, err error)
    36  	Decrypt(cryptotext string, key []byte) (string, error)
    37  }
    38  
    39  // GetCrypto get the crypto plugin
    40  func GetCryptoManager() CryptoManager {
    41  	if cryptoManager != nil {
    42  		return cryptoManager
    43  	}
    44  
    45  	cryptoManagerOnce.Do(func() {
    46  		var (
    47  			entries []ConfigEntry
    48  		)
    49  		if len(config.Crypto.Entries) != 0 {
    50  			entries = append(entries, config.Crypto.Entries...)
    51  		} else {
    52  			entries = append(entries, ConfigEntry{
    53  				Name:   config.Crypto.Name,
    54  				Option: config.Crypto.Option,
    55  			})
    56  		}
    57  		cryptoManager = &defaultCryptoManager{
    58  			cryptos: make(map[string]Crypto),
    59  			options: entries,
    60  		}
    61  
    62  		if err := cryptoManager.Initialize(); err != nil {
    63  			log.Errorf("Crypto plugin init err: %s", err.Error())
    64  			os.Exit(-1)
    65  		}
    66  	})
    67  	return cryptoManager
    68  }
    69  
    70  // CryptoManager crypto algorithm manager
    71  type CryptoManager interface {
    72  	Name() string
    73  	Initialize() error
    74  	Destroy() error
    75  	GetCryptoAlgoNames() []string
    76  	GetCrypto(algo string) (Crypto, error)
    77  }
    78  
    79  // defaultCryptoManager crypto algorithm manager
    80  type defaultCryptoManager struct {
    81  	cryptos map[string]Crypto
    82  	options []ConfigEntry
    83  }
    84  
    85  func (c *defaultCryptoManager) Name() string {
    86  	return "CryptoManager"
    87  }
    88  
    89  func (c *defaultCryptoManager) Initialize() error {
    90  	for i := range c.options {
    91  		entry := c.options[i]
    92  		item, exist := pluginSet[entry.Name]
    93  		if !exist {
    94  			log.Errorf("plugin Crypto not found target: %s", entry.Name)
    95  			continue
    96  		}
    97  		crypto, ok := item.(Crypto)
    98  		if !ok {
    99  			log.Errorf("plugin target: %s not Crypto", entry.Name)
   100  			continue
   101  		}
   102  		if err := crypto.Initialize(&entry); err != nil {
   103  			return err
   104  		}
   105  		c.cryptos[entry.Name] = crypto
   106  	}
   107  	return nil
   108  }
   109  
   110  func (c *defaultCryptoManager) Destroy() error {
   111  	for i := range c.cryptos {
   112  		if err := c.cryptos[i].Destroy(); err != nil {
   113  			return err
   114  		}
   115  	}
   116  	return nil
   117  }
   118  
   119  func (c *defaultCryptoManager) GetCryptoAlgoNames() []string {
   120  	var names []string
   121  	for name := range c.cryptos {
   122  		names = append(names, name)
   123  	}
   124  	return names
   125  }
   126  
   127  func (c *defaultCryptoManager) GetCrypto(algo string) (Crypto, error) {
   128  	crypto, ok := c.cryptos[algo]
   129  	if !ok {
   130  		log.Errorf("plugin Crypto not found target: %s", algo)
   131  		return nil, fmt.Errorf("plugin Crypto not found target: %s", algo)
   132  	}
   133  	return crypto, nil
   134  }