github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/offering/openshift/ca/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 openshiftca 20 21 import ( 22 "context" 23 "fmt" 24 25 current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1" 26 config "github.com/IBM-Blockchain/fabric-operator/operatorconfig" 27 k8sclient "github.com/IBM-Blockchain/fabric-operator/pkg/k8s/controllerclient" 28 "github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources" 29 resourcemanager "github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources/manager" 30 baseca "github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/ca" 31 basecaoverride "github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/ca/override" 32 "github.com/IBM-Blockchain/fabric-operator/pkg/offering/common" 33 "github.com/IBM-Blockchain/fabric-operator/pkg/offering/openshift/ca/override" 34 "github.com/IBM-Blockchain/fabric-operator/pkg/operatorerrors" 35 "github.com/IBM-Blockchain/fabric-operator/version" 36 routev1 "github.com/openshift/api/route/v1" 37 "github.com/pkg/errors" 38 v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 39 "k8s.io/apimachinery/pkg/runtime" 40 "sigs.k8s.io/controller-runtime/pkg/client" 41 logf "sigs.k8s.io/controller-runtime/pkg/log" 42 "sigs.k8s.io/controller-runtime/pkg/reconcile" 43 ) 44 45 var log = logf.Log.WithName("openshift_ca") 46 47 type Override interface { 48 baseca.Override 49 CARoute(object v1.Object, route *routev1.Route, action resources.Action) error 50 OperationsRoute(object v1.Object, route *routev1.Route, action resources.Action) error 51 } 52 53 var _ baseca.IBPCA = &CA{} 54 55 type CA struct { 56 *baseca.CA 57 58 CARouteManager resources.Manager 59 OperationsRouteManager resources.Manager 60 61 Override Override 62 } 63 64 func New(client k8sclient.Client, scheme *runtime.Scheme, config *config.Config) *CA { 65 o := &override.Override{ 66 Override: basecaoverride.Override{ 67 Client: client, 68 }, 69 } 70 ca := &CA{ 71 CA: baseca.New(client, scheme, config, o), 72 Override: o, 73 } 74 ca.CreateManagers() 75 return ca 76 } 77 78 func (ca *CA) CreateManagers() { 79 resourceManager := resourcemanager.New(ca.Client, ca.Scheme) 80 ca.CARouteManager = resourceManager.CreateRouteManager("ca", ca.Override.CARoute, ca.GetLabels, ca.Config.CAInitConfig.RouteFile) 81 ca.OperationsRouteManager = resourceManager.CreateRouteManager("operations", ca.Override.OperationsRoute, ca.GetLabels, ca.Config.CAInitConfig.RouteFile) 82 } 83 84 func (ca *CA) Reconcile(instance *current.IBPCA, update baseca.Update) (common.Result, error) { 85 86 var err error 87 88 versionSet, err := ca.SetVersion(instance) 89 if err != nil { 90 return common.Result{}, errors.Wrap(err, fmt.Sprintf("failed updating CR '%s' to version '%s'", instance.Name, version.Operator)) 91 } 92 if versionSet { 93 log.Info("Instance version updated, requeuing request...") 94 return common.Result{ 95 Result: reconcile.Result{ 96 Requeue: true, 97 }, 98 }, nil 99 } 100 101 instanceUpdated, err := ca.PreReconcileChecks(instance, update) 102 if err != nil { 103 return common.Result{}, errors.Wrap(err, "failed pre reconcile checks") 104 } 105 106 if instanceUpdated { 107 log.Info("Updating instance after pre reconcile checks") 108 err := ca.Client.Patch(context.TODO(), instance, nil, k8sclient.PatchOption{ 109 Resilient: &k8sclient.ResilientPatch{ 110 Retry: 3, 111 Into: ¤t.IBPCA{}, 112 Strategy: client.MergeFrom, 113 }, 114 }) 115 if err != nil { 116 return common.Result{}, errors.Wrap(err, "failed to update instance") 117 } 118 119 log.Info("Instance updated, requeuing request...") 120 return common.Result{ 121 Result: reconcile.Result{ 122 Requeue: true, 123 }, 124 }, nil 125 } 126 127 err = ca.AddTLSCryptoIfMissing(instance, ca.GetEndpointsDNS(instance)) 128 if err != nil { 129 return common.Result{}, errors.Wrap(err, "failed to generate tls crypto") 130 } 131 132 err = ca.Initialize(instance, update) 133 if err != nil { 134 return common.Result{}, operatorerrors.Wrap(err, operatorerrors.CAInitilizationFailed, "failed to initialize ca") 135 } 136 137 err = ca.ReconcileManagers(instance, update) 138 if err != nil { 139 return common.Result{}, errors.Wrap(err, "failed to reconcile managers") 140 } 141 142 if update.CATagUpdated() { 143 if err := ca.ReconcileFabricCAMigration(instance); err != nil { 144 return common.Result{}, operatorerrors.Wrap(err, operatorerrors.FabricCAMigrationFailed, "failed to migrate fabric ca versions") 145 } 146 } 147 148 err = ca.UpdateConnectionProfile(instance) 149 if err != nil { 150 return common.Result{}, errors.Wrap(err, "failed to create connection profile") 151 } 152 153 err = ca.CheckStates(instance) 154 if err != nil { 155 return common.Result{}, errors.Wrap(err, "failed to check and restore state") 156 } 157 158 status, err := ca.CheckCertificates(instance) 159 if err != nil { 160 return common.Result{}, errors.Wrap(err, "failed to check for expiring certificates") 161 } 162 163 if update.CACryptoUpdated() { 164 err = ca.Restart.ForTLSReenroll(instance) 165 if err != nil { 166 return common.Result{}, errors.Wrap(err, "failed to update restart config") 167 } 168 } 169 170 err = ca.HandleActions(instance, update) 171 if err != nil { 172 return common.Result{}, err 173 } 174 175 err = ca.HandleRestart(instance, update) 176 if err != nil { 177 return common.Result{}, err 178 } 179 180 return common.Result{ 181 Status: status, 182 }, nil 183 } 184 185 func (ca *CA) ReconcileManagers(instance *current.IBPCA, update baseca.Update) error { 186 err := ca.CA.ReconcileManagers(instance, update) 187 if err != nil { 188 return err 189 } 190 191 err = ca.CARouteManager.Reconcile(instance, update.SpecUpdated()) 192 if err != nil { 193 return errors.Wrap(err, "failed CA Route reconciliation") 194 } 195 196 err = ca.OperationsRouteManager.Reconcile(instance, update.SpecUpdated()) 197 if err != nil { 198 return errors.Wrap(err, "failed Operations Route reconciliation") 199 } 200 201 return nil 202 }