From 80acfa9955fe98030f29bf7cdbd76987f5c43623 Mon Sep 17 00:00:00 2001 From: David VIEJO Date: Sun, 5 Nov 2023 23:52:38 +0100 Subject: [PATCH] Update to fix bugs --- .../v1alpha1/hlf_types.go | 3 + .../hlf.kungfusoftware.es_fabriccas.yaml | 6 +- controllers/ca/ca_controller.go | 8 +- controllers/chaincode/chaincode_controller.go | 5 +- controllers/identity/identity_controller.go | 3 +- kubectl-hlf/cmd/chaincode/query.go | 1 + kubectl-hlf/cmd/channel/channel.go | 1 + kubectl-hlf/cmd/channel/signupdate.go | 143 ++++++++++++++++++ kubectl-hlf/cmd/peer/create.go | 7 +- 9 files changed, 163 insertions(+), 14 deletions(-) create mode 100644 kubectl-hlf/cmd/channel/signupdate.go diff --git a/api/hlf.kungfusoftware.es/v1alpha1/hlf_types.go b/api/hlf.kungfusoftware.es/v1alpha1/hlf_types.go index 5a28e87b..204f4e98 100644 --- a/api/hlf.kungfusoftware.es/v1alpha1/hlf_types.go +++ b/api/hlf.kungfusoftware.es/v1alpha1/hlf_types.go @@ -854,6 +854,9 @@ type FabricCAClientAuth struct { CertFile []string `json:"cert_file"` } type SecretRef struct { + // +optional + // +nullable + // +kubebuilder:validation:Optional Name string `json:"name"` } type SecretRefNSKey struct { diff --git a/config/crd/bases/hlf.kungfusoftware.es_fabriccas.yaml b/config/crd/bases/hlf.kungfusoftware.es_fabriccas.yaml index a96110bf..079406e7 100644 --- a/config/crd/bases/hlf.kungfusoftware.es_fabriccas.yaml +++ b/config/crd/bases/hlf.kungfusoftware.es_fabriccas.yaml @@ -914,9 +914,8 @@ spec: nullable: true properties: name: + nullable: true type: string - required: - - name type: object required: - cert @@ -1661,9 +1660,8 @@ spec: nullable: true properties: name: + nullable: true type: string - required: - - name type: object required: - cert diff --git a/controllers/ca/ca_controller.go b/controllers/ca/ca_controller.go index fdf2ad3b..b0dc5fe9 100644 --- a/controllers/ca/ca_controller.go +++ b/controllers/ca/ca_controller.go @@ -488,7 +488,7 @@ func GetConfig(conf *hlfv1alpha1.FabricCA, client *kubernetes.Clientset, chartNa var caRef *SecretRef signCert, signKey, err := getExistingSignCrypto(client, chartName, namespace) if err != nil { - if conf.Spec.CA.CA != nil && conf.Spec.CA.CA.SecretRef != nil { + if conf.Spec.CA.CA != nil && conf.Spec.CA.CA.SecretRef != nil && conf.Spec.CA.CA.SecretRef.Name != "" { caRef = &SecretRef{ SecretName: conf.Spec.CA.CA.SecretRef.Name, } @@ -505,7 +505,7 @@ func GetConfig(conf *hlfv1alpha1.FabricCA, client *kubernetes.Clientset, chartNa var caTLSSignRef *SecretRef caTLSSignCert, caTLSSignKey, err := getExistingSignTLSCrypto(client, chartName, namespace) if err != nil { - if conf.Spec.TLSCA.CA != nil && conf.Spec.TLSCA.CA.SecretRef != nil { + if conf.Spec.TLSCA.CA != nil && conf.Spec.TLSCA.CA.SecretRef != nil && conf.Spec.TLSCA.CA.SecretRef.Name != "" { caTLSSignRef = &SecretRef{ SecretName: conf.Spec.TLSCA.CA.SecretRef.Name, } @@ -784,7 +784,7 @@ func GetCAState(clientSet *kubernetes.Clientset, ca *hlfv1alpha1.FabricCA, relea ns, ) var signCrt *x509.Certificate - if ca.Spec.CA.CA != nil && ca.Spec.CA.CA.SecretRef != nil { + if ca.Spec.CA.CA != nil && ca.Spec.CA.CA.SecretRef != nil && ca.Spec.CA.CA.SecretRef.Name != "" { signCrt, _, err = getAlreadyExistingCrypto(clientSet, ca.Spec.CA.CA.SecretRef.Name, ns) if err != nil { return nil, err @@ -804,7 +804,7 @@ func GetCAState(clientSet *kubernetes.Clientset, ca *hlfv1alpha1.FabricCA, relea ns, ) var tlsCACrt *x509.Certificate - if ca.Spec.TLSCA.CA != nil && ca.Spec.TLSCA.CA.SecretRef != nil { + if ca.Spec.TLSCA.CA != nil && ca.Spec.TLSCA.CA.SecretRef != nil && ca.Spec.TLSCA.CA.SecretRef.Name != "" { tlsCACrt, _, err = getAlreadyExistingCrypto(clientSet, ca.Spec.TLSCA.CA.SecretRef.Name, ns) if err != nil { return nil, err diff --git a/controllers/chaincode/chaincode_controller.go b/controllers/chaincode/chaincode_controller.go index 25f69479..99bed325 100644 --- a/controllers/chaincode/chaincode_controller.go +++ b/controllers/chaincode/chaincode_controller.go @@ -491,9 +491,10 @@ func (r *FabricChaincodeReconciler) Reconcile(ctx context.Context, req ctrl.Requ r.setConditionStatus(ctx, fabricChaincode, hlfv1alpha1.FailedStatus, false, err, false) return r.updateCRStatusOrFailReconcile(ctx, r.Log, fabricChaincode) } + } else { + r.setConditionStatus(ctx, fabricChaincode, hlfv1alpha1.FailedStatus, false, err, false) + return r.updateCRStatusOrFailReconcile(ctx, r.Log, fabricChaincode) } - r.setConditionStatus(ctx, fabricChaincode, hlfv1alpha1.FailedStatus, false, err, false) - return r.updateCRStatusOrFailReconcile(ctx, r.Log, fabricChaincode) } else { deployment.Spec = appv1Deployment.Spec if cryptoData.Updated { diff --git a/controllers/identity/identity_controller.go b/controllers/identity/identity_controller.go index 0d4e6157..4ace7440 100644 --- a/controllers/identity/identity_controller.go +++ b/controllers/identity/identity_controller.go @@ -71,6 +71,7 @@ func (r *FabricIdentityReconciler) addFinalizer(reqLogger logr.Logger, m *hlfv1a // +kubebuilder:rbac:groups=hlf.kungfusoftware.es,resources=fabricidentities/finalizers,verbs=get;update;patch func (r *FabricIdentityReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { reqLogger := r.Log.WithValues("hlf", req.NamespacedName) + reqLogger.Info("Reconciling FabricIdentity") fabricIdentity := &hlfv1alpha1.FabricIdentity{} err := r.Get(ctx, req.NamespacedName, fabricIdentity) @@ -283,7 +284,7 @@ func (r *FabricIdentityReconciler) Reconcile(ctx context.Context, req ctrl.Reque return r.updateCRStatusOrFailReconcile(ctx, r.Log, fabricIdentity) } return ctrl.Result{ - RequeueAfter: 60 * time.Second, + RequeueAfter: 10 * 60 * time.Second, }, nil } diff --git a/kubectl-hlf/cmd/chaincode/query.go b/kubectl-hlf/cmd/chaincode/query.go index e4363ad7..8e452436 100644 --- a/kubectl-hlf/cmd/chaincode/query.go +++ b/kubectl-hlf/cmd/chaincode/query.go @@ -76,6 +76,7 @@ func (c *queryChaincodeCmd) run(out io.Writer) error { } return nil } + func newQueryChaincodeCMD(out io.Writer, errOut io.Writer) *cobra.Command { c := &queryChaincodeCmd{} cmd := &cobra.Command{ diff --git a/kubectl-hlf/cmd/channel/channel.go b/kubectl-hlf/cmd/channel/channel.go index 43a432b9..25724279 100644 --- a/kubectl-hlf/cmd/channel/channel.go +++ b/kubectl-hlf/cmd/channel/channel.go @@ -14,6 +14,7 @@ func NewChannelCmd(stdOut io.Writer, stdErr io.Writer) *cobra.Command { newUpdateChannelCMD(stdOut, stdErr), newInspectChannelCMD(stdOut, stdErr), newTopChannelCMD(stdOut, stdErr), + newSignUpdateChannelCMD(stdOut, stdErr), ) return channelCmd } diff --git a/kubectl-hlf/cmd/channel/signupdate.go b/kubectl-hlf/cmd/channel/signupdate.go new file mode 100644 index 00000000..3283f66a --- /dev/null +++ b/kubectl-hlf/cmd/channel/signupdate.go @@ -0,0 +1,143 @@ +package channel + +import ( + "bytes" + "fmt" + "github.com/golang/protobuf/proto" + "github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt" + "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp" + "github.com/hyperledger/fabric-sdk-go/pkg/core/config" + "github.com/hyperledger/fabric-sdk-go/pkg/core/cryptosuite" + "github.com/hyperledger/fabric-sdk-go/pkg/core/cryptosuite/bccsp/sw" + "github.com/hyperledger/fabric-sdk-go/pkg/fab" + "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk" + mspimpl "github.com/hyperledger/fabric-sdk-go/pkg/msp" + "github.com/spf13/cobra" + "gopkg.in/yaml.v3" + "io" + "io/ioutil" +) + +type signUpdateChannelCmd struct { + configPath string + channelName string + userName string + file string + mspID string + signatures []string + output string + identity string +} + +func (c *signUpdateChannelCmd) validate() error { + return nil +} + +type identity struct { + Cert Pem `json:"cert"` + Key Pem `json:"key"` +} +type Pem struct { + Pem string +} + +func (c *signUpdateChannelCmd) run(out io.Writer) error { + configBackend := config.FromFile(c.configPath) + sdk, err := fabsdk.New(configBackend) + if err != nil { + return err + } + org1AdminClientContext := sdk.Context( + fabsdk.WithUser(c.userName), + fabsdk.WithOrg(c.mspID), + ) + resClient, err := resmgmt.New(org1AdminClientContext) + if err != nil { + return err + } + updateEnvelopeBytes, err := ioutil.ReadFile(c.file) + if err != nil { + return err + } + configUpdateReader := bytes.NewReader(updateEnvelopeBytes) + sdkConfig, err := sdk.Config() + if err != nil { + return err + } + cryptoConfig := cryptosuite.ConfigFromBackend(sdkConfig) + cryptoSuite, err := sw.GetSuiteByConfig(cryptoConfig) + if err != nil { + return err + } + userStore := mspimpl.NewMemoryUserStore() + endpointConfig, err := fab.ConfigFromBackend(sdkConfig) + if err != nil { + return err + } + identityManager, err := mspimpl.NewIdentityManager(c.mspID, userStore, cryptoSuite, endpointConfig) + if err != nil { + return err + } + identityBytes, err := ioutil.ReadFile(c.identity) + if err != nil { + return err + } + id := &identity{} + err = yaml.Unmarshal(identityBytes, id) + if err != nil { + return err + } + signingIdentity, err := identityManager.CreateSigningIdentity( + msp.WithPrivateKey([]byte(id.Key.Pem)), + msp.WithCert([]byte(id.Cert.Pem)), + ) + if err != nil { + return err + } + signature, err := resClient.CreateConfigSignatureFromReader(signingIdentity, configUpdateReader) + if err != nil { + return err + } + signatureBytes, err := proto.Marshal(signature) + if err != nil { + return err + } + if c.output != "" { + err = ioutil.WriteFile(c.output, signatureBytes, 0644) + if err != nil { + return err + } + } else { + _, err = fmt.Fprint(out, signatureBytes) + if err != nil { + return err + } + } + return nil +} +func newSignUpdateChannelCMD(stdOut io.Writer, stdErr io.Writer) *cobra.Command { + c := &signUpdateChannelCmd{} + cmd := &cobra.Command{ + Use: "signupdate", + RunE: func(cmd *cobra.Command, args []string) error { + if err := c.validate(); err != nil { + return err + } + return c.run(stdOut) + }, + } + persistentFlags := cmd.PersistentFlags() + persistentFlags.StringVarP(&c.mspID, "mspid", "", "", "MSP ID of the organization") + persistentFlags.StringVarP(&c.channelName, "channel", "", "", "Channel name") + persistentFlags.StringVarP(&c.configPath, "config", "", "", "Configuration file for the SDK") + persistentFlags.StringVarP(&c.identity, "identity", "", "", "Identity file") + persistentFlags.StringVarP(&c.userName, "user", "", "", "User name for the transaction") + persistentFlags.StringVarP(&c.file, "file", "f", "", "Config update file") + persistentFlags.StringVarP(&c.output, "output", "o", "", "Output signature") + cmd.MarkPersistentFlagRequired("mspid") + cmd.MarkPersistentFlagRequired("channel") + cmd.MarkPersistentFlagRequired("config") + cmd.MarkPersistentFlagRequired("user") + cmd.MarkPersistentFlagRequired("file") + return cmd +} diff --git a/kubectl-hlf/cmd/peer/create.go b/kubectl-hlf/cmd/peer/create.go index 710f7487..b99dad81 100644 --- a/kubectl-hlf/cmd/peer/create.go +++ b/kubectl-hlf/cmd/peer/create.go @@ -52,6 +52,7 @@ type Options struct { CAPort int CAHost string ImagePullSecrets []string + Env []string } func (o Options) Validate() error { @@ -62,12 +63,11 @@ type createCmd struct { out io.Writer errOut io.Writer peerOpts Options - Env []string } func (c *createCmd) handleEnv() ([]corev1.EnvVar, error) { var env []corev1.EnvVar - for _, literalSource := range c.Env { + for _, literalSource := range c.peerOpts.Env { keyName, value, err := ParseEnv(literalSource) if err != nil { return nil, err @@ -487,6 +487,7 @@ func getPeerResourceRequirements() (*corev1.ResourceRequirements, error) { }, }, nil } + func newCreatePeerCmd(out io.Writer, errOut io.Writer) *cobra.Command { c := createCmd{out: out, errOut: errOut} cmd := &cobra.Command{ @@ -532,6 +533,6 @@ func newCreatePeerCmd(out io.Writer, errOut io.Writer) *cobra.Command { f.StringVarP(&c.peerOpts.CouchDBImage, "couchdb-repository", "", helpers.DefaultCouchDBImage, "CouchDB image") f.StringVarP(&c.peerOpts.CouchDBTag, "couchdb-tag", "", helpers.DefaultCouchDBVersion, "CouchDB version") f.StringVarP(&c.peerOpts.CouchDBPassword, "couchdb-password", "", "", "CouchDB password") - f.StringArrayVarP(&c.Env, "env", "e", []string{}, "Environment variable for the Chaincode (key=value)") + f.StringArrayVarP(&c.peerOpts.Env, "env", "e", []string{}, "Environment variable for the Chaincode (key=value)") return cmd }