github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/offering/k8s/orderer/node.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 k8sorderer 20 21 import ( 22 "context" 23 "fmt" 24 "strings" 25 26 current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1" 27 commoninit "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/common" 28 k8sclient "github.com/IBM-Blockchain/fabric-operator/pkg/k8s/controllerclient" 29 "github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources" 30 resourcemanager "github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources/manager" 31 baseorderer "github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/orderer" 32 "github.com/IBM-Blockchain/fabric-operator/pkg/offering/common" 33 "github.com/IBM-Blockchain/fabric-operator/pkg/offering/k8s/orderer/override" 34 "github.com/IBM-Blockchain/fabric-operator/pkg/operatorerrors" 35 "github.com/IBM-Blockchain/fabric-operator/pkg/util" 36 "github.com/IBM-Blockchain/fabric-operator/version" 37 "github.com/pkg/errors" 38 networkingv1 "k8s.io/api/networking/v1" 39 networkingv1beta1 "k8s.io/api/networking/v1beta1" 40 v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 41 "sigs.k8s.io/controller-runtime/pkg/client" 42 "sigs.k8s.io/controller-runtime/pkg/reconcile" 43 ) 44 45 type Override interface { 46 baseorderer.Override 47 Ingress(v1.Object, *networkingv1.Ingress, resources.Action) error 48 Ingressv1beta1(v1.Object, *networkingv1beta1.Ingress, resources.Action) error 49 } 50 51 var _ baseorderer.IBPOrderer = &Node{} 52 53 type Node struct { 54 *baseorderer.Node 55 56 IngressManager resources.Manager 57 Ingressv1beta1Manager resources.Manager 58 59 Override Override 60 } 61 62 func NewNode(basenode *baseorderer.Node) *Node { 63 node := &Node{ 64 Node: basenode, 65 Override: &override.Override{}, 66 } 67 node.CreateManagers() 68 return node 69 } 70 71 func (n *Node) CreateManagers() { 72 override := n.Override 73 resourceManager := resourcemanager.New(n.Client, n.Scheme) 74 n.IngressManager = resourceManager.CreateIngressManager("", override.Ingress, n.GetLabels, n.Config.OrdererInitConfig.IngressFile) 75 n.Ingressv1beta1Manager = resourceManager.CreateIngressv1beta1Manager("", override.Ingressv1beta1, n.GetLabels, n.Config.OrdererInitConfig.Ingressv1beta1File) 76 } 77 78 func (n *Node) Reconcile(instance *current.IBPOrderer, update baseorderer.Update) (common.Result, error) { 79 var err error 80 var status *current.CRStatus 81 82 log.Info(fmt.Sprintf("Reconciling node instance '%s' ... update: %+v", instance.Name, update)) 83 84 versionSet, err := n.SetVersion(instance) 85 if err != nil { 86 return common.Result{}, errors.Wrap(err, fmt.Sprintf("failed updating CR '%s' to version '%s'", instance.Name, version.Operator)) 87 } 88 if versionSet { 89 log.Info("Instance version updated, requeuing request...") 90 return common.Result{ 91 Result: reconcile.Result{ 92 Requeue: true, 93 }, 94 OverrideUpdateStatus: true, 95 }, nil 96 } 97 98 instanceUpdated, err := n.PreReconcileChecks(instance, update) 99 if err != nil { 100 return common.Result{}, errors.Wrap(err, "failed pre reconcile checks") 101 } 102 externalEndpointUpdated := n.UpdateExternalEndpoint(instance) 103 104 if instanceUpdated || externalEndpointUpdated { 105 log.Info(fmt.Sprintf("Updating instance after pre reconcile checks: %t, updating external endpoint: %t", 106 instanceUpdated, externalEndpointUpdated)) 107 108 err = n.Client.Patch(context.TODO(), instance, nil, k8sclient.PatchOption{ 109 Resilient: &k8sclient.ResilientPatch{ 110 Retry: 3, 111 Into: ¤t.IBPOrderer{}, 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 during reconcile checks, request will be requeued...") 120 return common.Result{ 121 Result: reconcile.Result{ 122 Requeue: true, 123 }, 124 Status: ¤t.CRStatus{ 125 Type: current.Initializing, 126 Reason: "Setting default values for either zone, region, and/or external endpoint", 127 Message: "Operator has updated spec with defaults as part of initialization", 128 }, 129 OverrideUpdateStatus: true, 130 }, nil 131 } 132 133 err = n.Initialize(instance, update) 134 if err != nil { 135 return common.Result{}, operatorerrors.Wrap(err, operatorerrors.OrdererInitilizationFailed, "failed to initialize orderer node") 136 } 137 138 if update.OrdererTagUpdated() { 139 if err := n.ReconcileFabricOrdererMigration(instance); err != nil { 140 return common.Result{}, operatorerrors.Wrap(err, operatorerrors.FabricOrdererMigrationFailed, "failed to migrate fabric orderer versions") 141 } 142 } 143 144 if update.MigrateToV2() { 145 if err := n.FabricOrdererMigrationV2_0(instance); err != nil { 146 return common.Result{}, operatorerrors.Wrap(err, operatorerrors.FabricOrdererMigrationFailed, "failed to migrate fabric orderer to version v2.x") 147 } 148 } 149 150 if update.MigrateToV24() { 151 if err := n.FabricOrdererMigrationV2_4(instance); err != nil { 152 return common.Result{}, operatorerrors.Wrap(err, operatorerrors.FabricOrdererMigrationFailed, "failed to migrate fabric orderer to version v2.4.x") 153 } 154 } 155 156 err = n.ReconcileManagers(instance, update, nil) 157 if err != nil { 158 return common.Result{}, errors.Wrap(err, "failed to reconcile managers") 159 } 160 161 err = n.UpdateConnectionProfile(instance) 162 if err != nil { 163 return common.Result{}, errors.Wrap(err, "failed to create connection profile") 164 } 165 166 err = n.CheckStates(instance) 167 if err != nil { 168 return common.Result{}, errors.Wrap(err, "failed to check and restore state") 169 } 170 171 err = n.UpdateParentStatus(instance) 172 if err != nil { 173 return common.Result{}, errors.Wrap(err, "failed to update parent's status") 174 } 175 176 status, result, err := n.CustomLogic(instance, update) 177 if err != nil { 178 return common.Result{}, errors.Wrap(err, "failed to run custom offering logic ") 179 } 180 if result != nil { 181 log.Info(fmt.Sprintf("Finished reconciling '%s' with Custom Logic result", instance.GetName())) 182 return *result, nil 183 } 184 185 if update.EcertUpdated() { 186 log.Info("Ecert was updated") 187 // Request deployment restart for tls cert update 188 err = n.Restart.ForCertUpdate(commoninit.ECERT, instance) 189 if err != nil { 190 return common.Result{}, errors.Wrap(err, "failed to update restart config") 191 } 192 } 193 194 if update.TLSCertUpdated() { 195 log.Info("TLS cert was updated") 196 // Request deployment restart for ecert update 197 err = n.Restart.ForCertUpdate(commoninit.TLS, instance) 198 if err != nil { 199 return common.Result{}, errors.Wrap(err, "failed to update restart config") 200 } 201 } 202 203 if update.MSPUpdated() { 204 err = n.UpdateMSPCertificates(instance) 205 if err != nil { 206 if err != nil { 207 return common.Result{}, errors.Wrap(err, "failed to update certificates passed in MSP spec") 208 } 209 } 210 } 211 212 if err := n.HandleActions(instance, update); err != nil { 213 return common.Result{}, err 214 } 215 216 if err := n.HandleRestart(instance, update); err != nil { 217 return common.Result{}, err 218 } 219 220 return common.Result{ 221 Status: status, 222 }, nil 223 } 224 225 func (n *Node) ReconcileManagers(instance *current.IBPOrderer, updated baseorderer.Update, genesisBlock []byte) error { 226 err := n.Node.ReconcileManagers(instance, updated, genesisBlock) 227 if err != nil { 228 return err 229 } 230 231 update := updated.SpecUpdated() 232 233 err = n.ReconcileIngressManager(instance, update) 234 if err != nil { 235 return errors.Wrap(err, "failed Ingress reconciliation") 236 } 237 238 return nil 239 } 240 241 func (n *Node) ReconcileIngressManager(instance *current.IBPOrderer, update bool) error { 242 if n.Config.Operator.Globals.AllowKubernetesEighteen == "true" { 243 // check k8s version 244 version, err := util.GetServerVersion() 245 if err != nil { 246 return err 247 } 248 if strings.Compare(version.Minor, "19") < 0 { // v1beta 249 err = n.Ingressv1beta1Manager.Reconcile(instance, update) 250 if err != nil { 251 return errors.Wrap(err, "failed Ingressv1beta1 reconciliation") 252 } 253 } else { 254 err = n.IngressManager.Reconcile(instance, update) 255 if err != nil { 256 return errors.Wrap(err, "failed Ingress reconciliation") 257 } 258 } 259 } else { 260 err := n.IngressManager.Reconcile(instance, update) 261 if err != nil { 262 return errors.Wrap(err, "failed Ingress reconciliation") 263 } 264 } 265 return nil 266 }