github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/runtime/kubernetes/client/util.go (about)

     1  // Licensed under the Apache License, Version 2.0 (the "License");
     2  // you may not use this file except in compliance with the License.
     3  // You may obtain a copy of the License at
     4  //
     5  //     https://www.apache.org/licenses/LICENSE-2.0
     6  //
     7  // Unless required by applicable law or agreed to in writing, software
     8  // distributed under the License is distributed on an "AS IS" BASIS,
     9  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    10  // See the License for the specific language governing permissions and
    11  // limitations under the License.
    12  //
    13  // Original source: github.com/micro/go-micro/v3/util/kubernetes/client/util.go
    14  
    15  package client
    16  
    17  import (
    18  	"crypto/x509"
    19  	"encoding/pem"
    20  	"errors"
    21  	"fmt"
    22  	"io"
    23  	"io/ioutil"
    24  	"strings"
    25  	"text/template"
    26  )
    27  
    28  // renderTemplateFile renders template for a given resource into writer w
    29  func renderTemplate(resource string, w io.Writer, data interface{}) error {
    30  	t := template.Must(template.New("kubernetes").Parse(templates[resource]))
    31  
    32  	if err := t.Execute(w, data); err != nil {
    33  		return err
    34  	}
    35  
    36  	return nil
    37  }
    38  
    39  // COPIED FROM
    40  // https://github.com/kubernetes/kubernetes/blob/7a725418af4661067b56506faabc2d44c6d7703a/pkg/util/crypto/crypto.go
    41  
    42  // CertPoolFromFile returns an x509.CertPool containing the certificates in the given PEM-encoded file.
    43  // Returns an error if the file could not be read, a certificate could not be parsed, or if the file does not contain any certificates
    44  func CertPoolFromFile(filename string) (*x509.CertPool, error) {
    45  	certs, err := certificatesFromFile(filename)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  	pool := x509.NewCertPool()
    50  	for _, cert := range certs {
    51  		pool.AddCert(cert)
    52  	}
    53  	return pool, nil
    54  }
    55  
    56  // certificatesFromFile returns the x509.Certificates contained in the given PEM-encoded file.
    57  // Returns an error if the file could not be read, a certificate could not be parsed, or if the file does not contain any certificates
    58  func certificatesFromFile(file string) ([]*x509.Certificate, error) {
    59  	if len(file) == 0 {
    60  		return nil, errors.New("error reading certificates from an empty filename")
    61  	}
    62  	pemBlock, err := ioutil.ReadFile(file)
    63  	if err != nil {
    64  		return nil, err
    65  	}
    66  	certs, err := CertsFromPEM(pemBlock)
    67  	if err != nil {
    68  		return nil, fmt.Errorf("error reading %s: %s", file, err)
    69  	}
    70  	return certs, nil
    71  }
    72  
    73  // CertsFromPEM returns the x509.Certificates contained in the given PEM-encoded byte array
    74  // Returns an error if a certificate could not be parsed, or if the data does not contain any certificates
    75  func CertsFromPEM(pemCerts []byte) ([]*x509.Certificate, error) {
    76  	ok := false
    77  	certs := []*x509.Certificate{}
    78  	for len(pemCerts) > 0 {
    79  		var block *pem.Block
    80  		block, pemCerts = pem.Decode(pemCerts)
    81  		if block == nil {
    82  			break
    83  		}
    84  		// Only use PEM "CERTIFICATE" blocks without extra headers
    85  		if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
    86  			continue
    87  		}
    88  
    89  		cert, err := x509.ParseCertificate(block.Bytes)
    90  		if err != nil {
    91  			return certs, err
    92  		}
    93  
    94  		certs = append(certs, cert)
    95  		ok = true
    96  	}
    97  
    98  	if !ok {
    99  		return certs, errors.New("could not read any certificates")
   100  	}
   101  	return certs, nil
   102  }
   103  
   104  // Format is used to format a string value into a k8s valid name
   105  // https://kubernetes.io/docs/concepts/overview/working-with-objects/names/
   106  func Format(v string) string {
   107  	// to lower case
   108  	v = strings.ToLower(v)
   109  	// / to dashes
   110  	replaceChars := []string{"/", ".", "_"}
   111  	for _, s := range replaceChars {
   112  		v = strings.ReplaceAll(v, s, "-")
   113  	}
   114  
   115  	// limit to 253 chars
   116  	if len(v) > 253 {
   117  		v = v[:253]
   118  	}
   119  	// return new name
   120  	return v
   121  }