Skip to content

Commit

Permalink
Fix reconcile loop in chaincode controllers (#248)
Browse files Browse the repository at this point in the history
* Add revocation list support to FabricFollowerChannel and improve requeue logic in chaincode controllers

- Introduced a new `revocationList` field in `FabricFollowerChannelSpec` to manage certificate revocation lists.
- Enhanced the `updateCRStatusOrFailReconcile` method in chaincode controllers to requeue failed updates after 10 seconds and handle running status without requeuing.
- Implemented CRL parsing utility to support revocation list processing in the follower channel controller.
- Updated related CRD and deepcopy functions to accommodate the new revocation list feature.

Signed-off-by: David VIEJO <[email protected]>

* Update README.md for Helm and Istio installation instructions

- Updated Helm installation command for hlf-operator to version 1.11.1.
- Modified Istio installation command to specify ISTIO_VERSION as 1.23.3.

These changes ensure users are directed to the latest versions for better compatibility and performance.

Signed-off-by: David VIEJO <[email protected]>

---------

Signed-off-by: David VIEJO <[email protected]>
  • Loading branch information
dviejokfs authored Dec 4, 2024
1 parent e718292 commit 47482ee
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 16 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ To install helm: [https://helm.sh/docs/intro/install/](https://helm.sh/docs/intr
```bash
helm repo add kfs https://kfsoftware.github.io/hlf-helm-charts --force-update

helm install hlf-operator --version=1.11.0 -- kfs/hlf-operator
helm install hlf-operator --version=1.11.1 -- kfs/hlf-operator
```


Expand All @@ -137,7 +137,7 @@ kubectl krew install hlf

Install Istio binaries on the machine:
```bash
curl -L https://istio.io/downloadIstio | sh -
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.23.3 sh -
```

Install Istio on the Kubernetes cluster:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ spec:
- namespace
type: object
type: array
revocationList:
default: []
items:
type: string
nullable: true
type: array
required:
- anchorPeers
- externalPeersToJoin
Expand Down
17 changes: 12 additions & 5 deletions controllers/chaincode/approve/chaincode_approve_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,19 +315,26 @@ func (r *FabricChaincodeApproveReconciler) updateCRStatusOrFailReconcile(ctx con
if err := r.Status().Update(ctx, p); err != nil {
log.Error(err, fmt.Sprintf("%v failed to update the application status", ErrClientK8s))
return reconcile.Result{
Requeue: false,
RequeueAfter: 0,
Requeue: true,
RequeueAfter: time.Second * 10,
}, nil
}

// If status is failed, requeue after 1 minute
if p.Status.Status == hlfv1alpha1.FailedStatus {
return reconcile.Result{
RequeueAfter: 1 * time.Minute,
}, nil
}
r.Log.Info(fmt.Sprintf("Requeueing after 1 minute for %s", p.Name))

// If status is running/success, don't requeue
if p.Status.Status == hlfv1alpha1.RunningStatus {
return reconcile.Result{}, nil
}

// For any other status, requeue after 1 minute
return reconcile.Result{
Requeue: false,
RequeueAfter: 0,
RequeueAfter: 1 * time.Minute,
}, nil
}

Expand Down
16 changes: 12 additions & 4 deletions controllers/chaincode/commit/chaincode_commit_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,16 +241,24 @@ func (r *FabricChaincodeCommitReconciler) updateCRStatusOrFailReconcile(ctx cont
if err := r.Status().Update(ctx, p); err != nil {
log.Error(err, fmt.Sprintf("%v failed to update the application status", ErrClientK8s))
return reconcile.Result{
Requeue: false,
RequeueAfter: 0,
}, err
Requeue: true,
RequeueAfter: time.Second * 10,
}, nil
}

if p.Status.Status == hlfv1alpha1.FailedStatus {
return reconcile.Result{
RequeueAfter: 1 * time.Minute,
}, nil
}
return reconcile.Result{}, nil

if p.Status.Status == hlfv1alpha1.RunningStatus {
return reconcile.Result{}, nil
}

return reconcile.Result{
RequeueAfter: 1 * time.Minute,
}, nil
}

func (r *FabricChaincodeCommitReconciler) SetupWithManager(mgr ctrl.Manager) error {
Expand Down
18 changes: 16 additions & 2 deletions controllers/chaincode/install/chaincode_install_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,14 +459,28 @@ func (r *FabricChaincodeInstallReconciler) updateCRStatusOrFailReconcile(ctx con
reconcile.Result, error) {
if err := r.Status().Update(ctx, p); err != nil {
log.Error(err, fmt.Sprintf("%v failed to update the application status", ErrClientK8s))
return reconcile.Result{}, err
return reconcile.Result{
Requeue: true,
RequeueAfter: time.Second * 10,
}, nil
}

// If status is failed, requeue after 1 minute
if p.Status.Status == hlfv1alpha1.FailedStatus {
return reconcile.Result{
RequeueAfter: 1 * time.Minute,
}, nil
}
return reconcile.Result{}, nil

// If status is running/success, don't requeue
if p.Status.Status == hlfv1alpha1.RunningStatus {
return reconcile.Result{}, nil
}

// For any other status, requeue after 1 minute
return reconcile.Result{
RequeueAfter: 1 * time.Minute,
}, nil
}

func (r *FabricChaincodeInstallReconciler) SetupWithManager(mgr ctrl.Manager) error {
Expand Down
28 changes: 27 additions & 1 deletion controllers/followerchannel/followerchannel_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package followerchannel
import (
"bytes"
"context"
"crypto/x509/pkix"
"fmt"
"strings"
"time"
Expand Down Expand Up @@ -279,7 +280,6 @@ func (r *FabricFollowerChannelReconciler) Reconcile(ctx context.Context, req ctr
reqLogger.Info(fmt.Sprintf("Removed anchor peer %v", anchorPeer))
}
r.Log.Info(fmt.Sprintf("New anchor peers %v", anchorPeers))

for _, anchorPeer := range fabricFollowerChannel.Spec.AnchorPeers {
err = app.AddAnchorPeer(configtx.Address{
Host: anchorPeer.Host,
Expand All @@ -291,6 +291,32 @@ func (r *FabricFollowerChannelReconciler) Reconcile(ctx context.Context, req ctr
return r.updateCRStatusOrFailReconcile(ctx, r.Log, fabricFollowerChannel)
}
}

r.Log.Info("Setting CRL configuration")

msp := app.MSP()
mspConf, err := msp.Configuration()
if err != nil {
r.setConditionStatus(ctx, fabricFollowerChannel, hlfv1alpha1.FailedStatus, false, err, false)
return r.updateCRStatusOrFailReconcile(ctx, r.Log, fabricFollowerChannel)
}
var revocationList []*pkix.CertificateList
for _, revocation := range fabricFollowerChannel.Spec.RevocationList {
crl, err := utils.ParseCRL([]byte(revocation))
if err != nil {
r.setConditionStatus(ctx, fabricFollowerChannel, hlfv1alpha1.FailedStatus, false, err, false)
return r.updateCRStatusOrFailReconcile(ctx, r.Log, fabricFollowerChannel)
}
revocationList = append(revocationList, crl)
}
mspConf.RevocationList = revocationList
err = app.SetMSP(mspConf)
if err != nil {
r.setConditionStatus(ctx, fabricFollowerChannel, hlfv1alpha1.FailedStatus, false, err, false)
return r.updateCRStatusOrFailReconcile(ctx, r.Log, fabricFollowerChannel)
}
r.Log.Info("CRL configuration set")
r.Log.Info("Updating channel configuration")
configUpdateBytes, err := cftxGen.ComputeMarshaledUpdate(fabricFollowerChannel.Spec.Name)
if err != nil {
if !strings.Contains(err.Error(), "no differences detected between original and updated config") {
Expand Down
6 changes: 4 additions & 2 deletions controllers/mainchannel/mainchannel_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ func (r *FabricMainChannelReconciler) saveChannelConfig(ctx context.Context, fab

configMapName := fmt.Sprintf("%s-config", fabricMainChannel.ObjectMeta.Name)
configMapNamespace := "default"

r.Log.Info("Saving channel config into configmap", "configmap", configMapName)
return r.createOrUpdateConfigMap(ctx, configMapName, configMapNamespace, buf.String())
}

Expand Down Expand Up @@ -893,6 +893,9 @@ func (r *FabricMainChannelReconciler) mapToConfigTX(channel *hlfv1alpha1.FabricM
consenters := []orderer.Consenter{}
var smartBFTOptions *sb.Options
if channel.Spec.ChannelConfig.Orderer.OrdererType == hlfv1alpha1.OrdererConsensusBFT {
if len(channel.Spec.ChannelConfig.Orderer.ConsenterMapping) <= 4 {
return configtx.Channel{}, fmt.Errorf("consenter mapping needs to be at least 4")
}
ordererType = string(orderer.ConsensusTypeBFT)
for _, consenterItem := range channel.Spec.ChannelConfig.Orderer.ConsenterMapping {
identityCert, err := utils.ParseX509Certificate([]byte(consenterItem.Identity))
Expand Down Expand Up @@ -1373,7 +1376,6 @@ func updateChannelConfigTx(currentConfigTX configtx.ConfigTx, newConfigTx config
}

func updateOrdererChannelConfigTx(currentConfigTX configtx.ConfigTx, newConfigTx configtx.Channel) error {

ord, err := currentConfigTX.Orderer().Configuration()
if err != nil {
return errors.Wrapf(err, "failed to get application configuration")
Expand Down
22 changes: 22 additions & 0 deletions controllers/utils/crl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package utils

import (
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
)

func ParseCRL(crlBytes []byte) (*pkix.CertificateList, error) {
block, _ := pem.Decode(crlBytes)
if block == nil {
return nil, fmt.Errorf("failed to decode PEM block containing CRL")
}

crl, err := x509.ParseCRL(block.Bytes)
if err != nil {
return nil, fmt.Errorf("failed to parse CRL: %v", err)
}

return crl, nil
}
6 changes: 6 additions & 0 deletions pkg/apis/hlf.kungfusoftware.es/v1alpha1/hlf_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1602,6 +1602,7 @@ type FabricNetworkConfigOrgPeer struct {
type FabricNetworkConfigOrganization struct {
Peers []FabricNetworkConfigOrgPeer `json:"peers"`
}

type FabricNetworkConfigCA struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Expand Down Expand Up @@ -2758,6 +2759,11 @@ type FabricFollowerChannelSpec struct {
AnchorPeers []FabricFollowerChannelAnchorPeer `json:"anchorPeers"`
// Identity to use to interact with the peers and the orderers
HLFIdentity HLFIdentity `json:"hlfIdentity"`
// +nullable
// +optional
// +kubebuilder:validation:Optional
// +kubebuilder:default:={}
RevocationList []string `json:"revocationList"`
}

type FabricFollowerChannelAnchorPeer struct {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 47482ee

Please sign in to comment.