github.com/IBM-Blockchain/fabric-operator@v1.0.4/integration/helper/ca.go (about) 1 /* 2 * Copyright contributors to the Hyperledger Fabric Operator project 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Licensed under the Apache License, Version 2.0 (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 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package helper 20 21 import ( 22 "context" 23 "crypto/tls" 24 "crypto/x509" 25 "fmt" 26 "io/ioutil" 27 "net/http" 28 "os" 29 "os/exec" 30 "path/filepath" 31 "strings" 32 "time" 33 34 current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1" 35 "github.com/IBM-Blockchain/fabric-operator/integration" 36 ibpclient "github.com/IBM-Blockchain/fabric-operator/pkg/client" 37 38 k8serrors "k8s.io/apimachinery/pkg/api/errors" 39 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 40 "k8s.io/client-go/kubernetes" 41 42 "sigs.k8s.io/yaml" 43 ) 44 45 func CreateCA(crClient *ibpclient.IBPClient, ca *current.IBPCA) error { 46 result := crClient.Post().Namespace(ca.Namespace).Resource("ibpcas").Body(ca).Do(context.TODO()) 47 err := result.Error() 48 if !k8serrors.IsAlreadyExists(err) { 49 return err 50 } 51 return nil 52 } 53 54 type CA struct { 55 Domain string 56 Name string 57 Namespace string 58 WorkingDir string 59 60 CR *current.IBPCA 61 CRClient *ibpclient.IBPClient 62 KClient *kubernetes.Clientset 63 64 integration.NativeResourcePoller 65 } 66 67 func (ca *CA) PollForCRStatus() current.IBPCRStatusType { 68 crStatus := ¤t.IBPCA{} 69 70 result := ca.CRClient.Get().Namespace(ca.Namespace).Resource("ibpcas").Name(ca.Name).Do(context.TODO()) 71 // Not handling this because - integration test 72 _ = result.Into(crStatus) 73 74 return crStatus.Status.Type 75 } 76 77 func (ca *CA) HealthCheck(url string, cert []byte) bool { 78 rootCertPool := x509.NewCertPool() 79 rootCertPool.AppendCertsFromPEM(cert) 80 81 transport := http.DefaultTransport 82 transport.(*http.Transport).TLSClientConfig = &tls.Config{ 83 RootCAs: rootCertPool, 84 MinVersion: tls.VersionTLS12, // TLS 1.2 recommended, TLS 1.3 (current latest version) encouraged 85 } 86 87 client := http.Client{ 88 Transport: transport, 89 Timeout: 30 * time.Second, 90 } 91 92 _, err := client.Get(url) 93 if err != nil { 94 return false 95 } 96 97 return true 98 } 99 100 func (ca *CA) ConnectionProfile() (*current.CAConnectionProfile, error) { 101 cm, err := ca.KClient.CoreV1().ConfigMaps(ca.Namespace).Get(context.TODO(), fmt.Sprintf("%s-connection-profile", ca.CR.Name), metav1.GetOptions{}) 102 if err != nil { 103 return nil, err 104 } 105 106 data := cm.BinaryData["profile.json"] 107 108 profile := ¤t.CAConnectionProfile{} 109 err = yaml.Unmarshal(data, profile) 110 if err != nil { 111 return nil, err 112 } 113 114 return profile, nil 115 } 116 117 func (ca *CA) Address() string { 118 return fmt.Sprintf("%s-%s-ca.%s", ca.Namespace, ca.Name, ca.Domain) 119 } 120 121 func (ca *CA) Register(name string, secret string, userType string) *exec.Cmd { 122 url := fmt.Sprintf("https://%s", ca.Address()) 123 args := []string{ 124 "--tls.certfiles", ca.TLSPath(), 125 "--id.name", name, 126 "--id.secret", secret, 127 "--id.type", userType, 128 "-u", url, 129 "-d", 130 } 131 return GetCommand(filepath.Join(ca.WorkingDir, "bin/fabric-ca-client register"), args...) 132 } 133 134 func (ca *CA) Enroll(name string, secret string) *exec.Cmd { 135 url := fmt.Sprintf("https://%s:%s@%s", name, secret, ca.Address()) 136 args := []string{ 137 "--tls.certfiles", ca.TLSPath(), 138 "-u", url, 139 "-d", 140 } 141 return GetCommand(filepath.Join(ca.WorkingDir, "bin/fabric-ca-client enroll"), args...) 142 } 143 144 func (ca *CA) DeleteIdentity(name string) *exec.Cmd { 145 url := fmt.Sprintf("https://%s", ca.Address()) 146 args := []string{ 147 name, 148 "--tls.certfiles", ca.TLSPath(), 149 "-u", url, 150 "-d", 151 } 152 return GetCommand(filepath.Join(ca.WorkingDir, "bin/fabric-ca-client identity remove"), args...) 153 } 154 155 func (ca *CA) TLSToFile(cert []byte) error { 156 err := os.MkdirAll(filepath.Dir(ca.TLSPath()), 0750) 157 if err != nil { 158 return err 159 } 160 err = ioutil.WriteFile(ca.TLSPath(), cert, 0600) 161 if err != nil { 162 return err 163 } 164 return nil 165 } 166 167 func (ca *CA) TLSPath() string { 168 return filepath.Join(ca.WorkingDir, ca.Name, "tls-cert.pem") 169 } 170 171 func (ca *CA) JobWithPrefixFound(prefix, namespace string) bool { 172 jobs, err := ca.KClient.BatchV1().Jobs(namespace).List(context.TODO(), metav1.ListOptions{}) 173 if err != nil { 174 return false 175 } 176 177 for _, job := range jobs.Items { 178 if strings.HasPrefix(job.GetName(), prefix) { 179 return true 180 } 181 } 182 183 return false 184 }