diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 91a4a91c..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "go.goroot": "/Users/davidviejo/.goenv/versions/1.23.1", - "go.toolsEnvVars": { - "GOROOT": "/Users/davidviejo/.goenv/versions/1.23.1" - } - } \ No newline at end of file diff --git a/config/crd/bases/hlf.kungfusoftware.es_fabricmainchannels.yaml b/config/crd/bases/hlf.kungfusoftware.es_fabricmainchannels.yaml index a876a4d5..f7a71f04 100644 --- a/config/crd/bases/hlf.kungfusoftware.es_fabricmainchannels.yaml +++ b/config/crd/bases/hlf.kungfusoftware.es_fabricmainchannels.yaml @@ -319,6 +319,12 @@ spec: items: type: string type: array + revocationList: + default: [] + items: + type: string + nullable: true + type: array signRootCert: type: string tlsRootCert: @@ -400,6 +406,12 @@ spec: - namespace type: object type: array + revocationList: + default: [] + items: + type: string + nullable: true + type: array signCACert: type: string tlsCACert: diff --git a/controllers/followerchannel/followerchannel_controller.go b/controllers/followerchannel/followerchannel_controller.go index 5afef2a1..7fcd1751 100644 --- a/controllers/followerchannel/followerchannel_controller.go +++ b/controllers/followerchannel/followerchannel_controller.go @@ -293,14 +293,8 @@ func (r *FabricFollowerChannelReconciler) Reconcile(ctx context.Context, req ctr } 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 + // Then add the new CRLs for _, revocation := range fabricFollowerChannel.Spec.RevocationList { crl, err := utils.ParseCRL([]byte(revocation)) if err != nil { @@ -309,14 +303,30 @@ func (r *FabricFollowerChannelReconciler) Reconcile(ctx context.Context, req ctr } revocationList = append(revocationList, crl) } - mspConf.RevocationList = revocationList - err = app.SetMSP(mspConf) + + org, err := cftxGen.Application().Organization(mspID).Configuration() if err != nil { r.setConditionStatus(ctx, fabricFollowerChannel, hlfv1alpha1.FailedStatus, false, err, false) return r.updateCRStatusOrFailReconcile(ctx, r.Log, fabricFollowerChannel) } + org.MSP.RevocationList = revocationList + err = cftxGen.Application().SetOrganization(org) + 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") + updatedConfig := cftxGen.UpdatedConfig() + // convert to json and print it as log + var buf3 bytes.Buffer + err = protolator.DeepMarshalJSON(&buf3, updatedConfig) + if err != nil { + r.setConditionStatus(ctx, fabricFollowerChannel, hlfv1alpha1.FailedStatus, false, err, false) + return r.updateCRStatusOrFailReconcile(ctx, r.Log, fabricFollowerChannel) + } + r.Log.Info(fmt.Sprintf("Updated config: %s", buf2.String())) configUpdateBytes, err := cftxGen.ComputeMarshaledUpdate(fabricFollowerChannel.Spec.Name) if err != nil { if !strings.Contains(err.Error(), "no differences detected between original and updated config") { diff --git a/controllers/mainchannel/mainchannel_controller.go b/controllers/mainchannel/mainchannel_controller.go index b2f244a8..eaa0c7a5 100644 --- a/controllers/mainchannel/mainchannel_controller.go +++ b/controllers/mainchannel/mainchannel_controller.go @@ -826,6 +826,7 @@ func (r *FabricMainChannelReconciler) mapToConfigTX(channel *hlfv1alpha1.FabricM for _, ordererOrg := range channel.Spec.OrdererOrganizations { var tlsCACert *x509.Certificate var caCert *x509.Certificate + if ordererOrg.CAName != "" && ordererOrg.CANamespace != "" { certAuth, err := helpers.GetCertAuthByName( clientSet, @@ -854,7 +855,20 @@ func (r *FabricMainChannelReconciler) mapToConfigTX(channel *hlfv1alpha1.FabricM return configtx.Channel{}, err } } - ordererOrgs = append(ordererOrgs, r.mapOrdererOrg(ordererOrg.MSPID, ordererOrg.OrdererEndpoints, caCert, tlsCACert)) + + // Parse revocation list if provided + revocationList := []*pkix.CertificateList{} + if len(ordererOrg.RevocationList) > 0 { + for _, revocation := range ordererOrg.RevocationList { + crl, err := utils.ParseCRL([]byte(revocation)) + if err != nil { + return configtx.Channel{}, errors.Wrapf(err, "failed to parse revocation list for orderer org %s", ordererOrg.MSPID) + } + revocationList = append(revocationList, crl) + } + } + + ordererOrgs = append(ordererOrgs, r.mapOrdererOrg(ordererOrg.MSPID, ordererOrg.OrdererEndpoints, caCert, tlsCACert, revocationList)) } for _, ordererOrg := range channel.Spec.ExternalOrdererOrganizations { tlsCACert, err := utils.ParseX509Certificate([]byte(ordererOrg.TLSRootCert)) @@ -865,7 +879,15 @@ func (r *FabricMainChannelReconciler) mapToConfigTX(channel *hlfv1alpha1.FabricM if err != nil { return configtx.Channel{}, err } - ordererOrgs = append(ordererOrgs, r.mapOrdererOrg(ordererOrg.MSPID, ordererOrg.OrdererEndpoints, caCert, tlsCACert)) + revocationList := []*pkix.CertificateList{} + for _, revocation := range ordererOrg.RevocationList { + crl, err := utils.ParseCRL([]byte(revocation)) + if err != nil { + return configtx.Channel{}, err + } + revocationList = append(revocationList, crl) + } + ordererOrgs = append(ordererOrgs, r.mapOrdererOrg(ordererOrg.MSPID, ordererOrg.OrdererEndpoints, caCert, tlsCACert, revocationList)) } etcdRaftOptions := orderer.EtcdRaftOptions{ TickInterval: "500ms", @@ -1160,7 +1182,8 @@ func (r *FabricMainChannelReconciler) mapPolicy( } return policiesMap } -func (r *FabricMainChannelReconciler) mapOrdererOrg(mspID string, ordererEndpoints []string, caCert *x509.Certificate, tlsCACert *x509.Certificate) configtx.Organization { + +func (r *FabricMainChannelReconciler) mapOrdererOrg(mspID string, ordererEndpoints []string, caCert *x509.Certificate, tlsCACert *x509.Certificate, revocationList []*pkix.CertificateList) configtx.Organization { return configtx.Organization{ Name: mspID, Policies: map[string]configtx.Policy{ @@ -1206,7 +1229,7 @@ func (r *FabricMainChannelReconciler) mapOrdererOrg(mspID string, ordererEndpoin }, Admins: []*x509.Certificate{}, IntermediateCerts: []*x509.Certificate{}, - RevocationList: []*pkix.CertificateList{}, + RevocationList: revocationList, OrganizationalUnitIdentifiers: []membership.OUIdentifier{}, CryptoConfig: membership.CryptoConfig{}, TLSIntermediateCerts: []*x509.Certificate{}, @@ -1336,13 +1359,14 @@ func updateApplicationChannelConfigTx(currentConfigTX configtx.ConfigTx, newConf } } if !found { - log.Infof("Adding organization %s", organization.Name) + log.Infof("Adding organization %v", organization) err = currentConfigTX.Application().SetOrganization(organization) if err != nil { return errors.Wrapf(err, "failed to set organization %s", organization.Name) } } } + err = currentConfigTX.Application().SetPolicies( newConfigTx.Application.Policies, ) @@ -1438,20 +1462,20 @@ func updateOrdererChannelConfigTx(currentConfigTX configtx.ConfigTx, newConfigTx deleted := true needsUpdate := false var matchingNewConsenter orderer.Consenter - + for _, newConsenter := range newConfigTx.Orderer.EtcdRaft.Consenters { if newConsenter.Address.Host == consenter.Address.Host && newConsenter.Address.Port == consenter.Address.Port { deleted = false matchingNewConsenter = newConsenter // Check if TLS certs are different - if !bytes.Equal(newConsenter.ClientTLSCert.Raw, consenter.ClientTLSCert.Raw) || - !bytes.Equal(newConsenter.ServerTLSCert.Raw, consenter.ServerTLSCert.Raw) { + if !bytes.Equal(newConsenter.ClientTLSCert.Raw, consenter.ClientTLSCert.Raw) || + !bytes.Equal(newConsenter.ServerTLSCert.Raw, consenter.ServerTLSCert.Raw) { needsUpdate = true } break } } - + if deleted { log.Infof("Removing consenter %s:%d", consenter.Address.Host, consenter.Address.Port) err = currentConfigTX.Orderer().RemoveConsenter(consenter) @@ -1645,6 +1669,12 @@ func updateOrdererChannelConfigTx(currentConfigTX configtx.ConfigTx, newConfigTx return errors.Wrapf(err, "failed to add endpoint %s", endpoint) } } + + ordConfig.MSP.RevocationList = organization.MSP.RevocationList + err = currentConfigTX.Orderer().Organization(organization.Name).SetMSP(ordConfig.MSP) + if err != nil { + return errors.Wrapf(err, "failed to set organization %s", organization.Name) + } } else { log.Infof("Adding organization %s", organization.Name) err = currentConfigTX.Orderer().SetOrganization(organization) diff --git a/pkg/apis/hlf.kungfusoftware.es/v1alpha1/hlf_types.go b/pkg/apis/hlf.kungfusoftware.es/v1alpha1/hlf_types.go index 8a322240..8dd68292 100644 --- a/pkg/apis/hlf.kungfusoftware.es/v1alpha1/hlf_types.go +++ b/pkg/apis/hlf.kungfusoftware.es/v1alpha1/hlf_types.go @@ -2688,6 +2688,11 @@ type FabricMainChannelExternalOrdererOrganization struct { SignRootCert string `json:"signRootCert"` // Orderer endpoints for the organization in the channel configuration OrdererEndpoints []string `json:"ordererEndpoints"` + // +optional + // +nullable + // +kubebuilder:validation:Optional + // +kubebuilder:default:={} + RevocationList []string `json:"revocationList"` } type OrgCertsRef struct { } @@ -2720,6 +2725,11 @@ type FabricMainChannelOrdererOrganization struct { // +optional // Root certificate authority for signing SignCACert string `json:"signCACert"` + // +optional + // +nullable + // +kubebuilder:validation:Optional + // +kubebuilder:default:={} + RevocationList []string `json:"revocationList"` // Orderer endpoints for the organization in the channel configuration OrdererEndpoints []string `json:"ordererEndpoints"` // Orderer nodes within the kubernetes cluster to be added to the channel diff --git a/pkg/apis/hlf.kungfusoftware.es/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/hlf.kungfusoftware.es/v1alpha1/zz_generated.deepcopy.go index cbbf729b..5a26157a 100644 --- a/pkg/apis/hlf.kungfusoftware.es/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/hlf.kungfusoftware.es/v1alpha1/zz_generated.deepcopy.go @@ -212,6 +212,31 @@ func (in *Condition) DeepCopy() *Condition { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConsensusTypeValue) DeepCopyInto(out *ConsensusTypeValue) { + *out = *in + if in.value != nil { + in, out := &in.value, &out.value + *out = new(OrdererConsensusType) + **out = **in + } + if in.allowed != nil { + in, out := &in.allowed, &out.allowed + *out = make([]OrdererConsensusType, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsensusTypeValue. +func (in *ConsensusTypeValue) DeepCopy() *ConsensusTypeValue { + if in == nil { + return nil + } + out := new(ConsensusTypeValue) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Cors) DeepCopyInto(out *Cors) { *out = *in