github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-config/configtx/application.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package configtx 8 9 import ( 10 "errors" 11 "fmt" 12 13 "github.com/golang/protobuf/proto" 14 cb "github.com/hyperledger/fabric-protos-go/common" 15 pb "github.com/hyperledger/fabric-protos-go/peer" 16 ) 17 18 // Application is a copy of the orderer configuration with the addition of an anchor peers 19 // list in the organization definition. 20 type Application struct { 21 Organizations []Organization 22 Capabilities []string 23 Policies map[string]Policy 24 ACLs map[string]string 25 ModPolicy string 26 } 27 28 // ApplicationGroup encapsulates the part of the config that controls 29 // application channels. 30 type ApplicationGroup struct { 31 applicationGroup *cb.ConfigGroup 32 } 33 34 // ApplicationOrg encapsulates the parts of the config that control 35 // an application organization's configuration. 36 type ApplicationOrg struct { 37 orgGroup *cb.ConfigGroup 38 name string 39 } 40 41 // MSP returns an OrganizationMSP object that can be used to configure the organization's MSP. 42 func (a *ApplicationOrg) MSP() *OrganizationMSP { 43 return &OrganizationMSP{ 44 configGroup: a.orgGroup, 45 } 46 } 47 48 // Application returns the application group the updated config. 49 func (c *ConfigTx) Application() *ApplicationGroup { 50 applicationGroup := c.updated.ChannelGroup.Groups[ApplicationGroupKey] 51 return &ApplicationGroup{applicationGroup: applicationGroup} 52 } 53 54 // Organization returns the application org from the updated config. 55 func (a *ApplicationGroup) Organization(name string) *ApplicationOrg { 56 organizationGroup, ok := a.applicationGroup.Groups[name] 57 if !ok { 58 return nil 59 } 60 return &ApplicationOrg{name: name, orgGroup: organizationGroup} 61 } 62 63 // SetOrganization sets the organization config group for the given application 64 // org key in an existing Application configuration's Groups map. 65 // If the application org already exists in the current configuration, its value will be overwritten. 66 func (a *ApplicationGroup) SetOrganization(org Organization) error { 67 orgGroup, err := newApplicationOrgConfigGroup(org) 68 if err != nil { 69 return fmt.Errorf("failed to create application org %s: %v", org.Name, err) 70 } 71 72 a.applicationGroup.Groups[org.Name] = orgGroup 73 74 return nil 75 } 76 77 // RemoveOrganization removes an org from the Application group. 78 // Removal will panic if the application group does not exist. 79 func (a *ApplicationGroup) RemoveOrganization(orgName string) { 80 delete(a.applicationGroup.Groups, orgName) 81 } 82 83 // Configuration returns the existing application configuration values from a config 84 // transaction as an Application type. This can be used to retrieve existing values for the application 85 // prior to updating the application configuration. 86 func (a *ApplicationGroup) Configuration() (Application, error) { 87 var applicationOrgs []Organization 88 for orgName := range a.applicationGroup.Groups { 89 orgConfig, err := a.Organization(orgName).Configuration() 90 if err != nil { 91 return Application{}, fmt.Errorf("retrieving application org %s: %v", orgName, err) 92 } 93 94 applicationOrgs = append(applicationOrgs, orgConfig) 95 } 96 97 capabilities, err := a.Capabilities() 98 if err != nil { 99 return Application{}, fmt.Errorf("retrieving application capabilities: %v", err) 100 } 101 102 policies, err := a.Policies() 103 if err != nil { 104 return Application{}, fmt.Errorf("retrieving application policies: %v", err) 105 } 106 107 acls, err := a.ACLs() 108 if err != nil { 109 return Application{}, fmt.Errorf("retrieving application acls: %v", err) 110 } 111 112 return Application{ 113 Organizations: applicationOrgs, 114 Capabilities: capabilities, 115 Policies: policies, 116 ACLs: acls, 117 }, nil 118 } 119 120 // Configuration returns the existing application org configuration values 121 // from the updated config. 122 func (a *ApplicationOrg) Configuration() (Organization, error) { 123 org, err := getOrganization(a.orgGroup, a.name) 124 if err != nil { 125 return Organization{}, err 126 } 127 return org, nil 128 } 129 130 // Capabilities returns a map of enabled application capabilities 131 // from the updated config. 132 func (a *ApplicationGroup) Capabilities() ([]string, error) { 133 capabilities, err := getCapabilities(a.applicationGroup) 134 if err != nil { 135 return nil, fmt.Errorf("retrieving application capabilities: %v", err) 136 } 137 138 return capabilities, nil 139 } 140 141 // AddCapability sets capability to the provided channel config. 142 // If the provided capability already exists in current configuration, this action 143 // will be a no-op. 144 func (a *ApplicationGroup) AddCapability(capability string) error { 145 capabilities, err := a.Capabilities() 146 if err != nil { 147 return err 148 } 149 150 err = addCapability(a.applicationGroup, capabilities, AdminsPolicyKey, capability) 151 if err != nil { 152 return err 153 } 154 155 return nil 156 } 157 158 // RemoveCapability removes capability to the provided channel config. 159 func (a *ApplicationGroup) RemoveCapability(capability string) error { 160 capabilities, err := a.Capabilities() 161 if err != nil { 162 return err 163 } 164 165 err = removeCapability(a.applicationGroup, capabilities, AdminsPolicyKey, capability) 166 if err != nil { 167 return err 168 } 169 170 return nil 171 } 172 173 // Policies returns a map of policies for the application config group in 174 // the updatedconfig. 175 func (a *ApplicationGroup) Policies() (map[string]Policy, error) { 176 return getPolicies(a.applicationGroup.Policies) 177 } 178 179 // SetModPolicy sets the specified modification policy for the application group. 180 func (a *ApplicationGroup) SetModPolicy(modPolicy string) error { 181 if modPolicy == "" { 182 return errors.New("non empty mod policy is required") 183 } 184 185 a.applicationGroup.ModPolicy = modPolicy 186 187 return nil 188 } 189 190 // SetPolicy sets the specified policy in the application group's config policy map. 191 // If the policy already exists in current configuration, its value will be overwritten. 192 func (a *ApplicationGroup) SetPolicy(policyName string, policy Policy) error { 193 err := setPolicy(a.applicationGroup, policyName, policy) 194 if err != nil { 195 return fmt.Errorf("failed to set policy '%s': %v", policyName, err) 196 } 197 198 return nil 199 } 200 201 // SetPolicies sets the specified policies in the application group's config policy map. 202 // If the policies already exist in current configuration, the values will be replaced with new policies. 203 func (a *ApplicationGroup) SetPolicies(policies map[string]Policy) error { 204 err := setPolicies(a.applicationGroup, policies) 205 if err != nil { 206 return fmt.Errorf("failed to set policies: %v", err) 207 } 208 209 return nil 210 } 211 212 // RemovePolicy removes an existing policy from an application's configuration. 213 // Removal will panic if the application group does not exist. 214 func (a *ApplicationGroup) RemovePolicy(policyName string) error { 215 policies, err := a.Policies() 216 if err != nil { 217 return err 218 } 219 220 removePolicy(a.applicationGroup, policyName, policies) 221 return nil 222 } 223 224 // Policies returns the map of policies for a specific application org in 225 // the updated config. 226 func (a *ApplicationOrg) Policies() (map[string]Policy, error) { 227 return getPolicies(a.orgGroup.Policies) 228 } 229 230 // SetModPolicy sets the specified modification policy for the application organization group. 231 func (a *ApplicationOrg) SetModPolicy(modPolicy string) error { 232 if modPolicy == "" { 233 return errors.New("non empty mod policy is required") 234 } 235 236 a.orgGroup.ModPolicy = modPolicy 237 238 return nil 239 } 240 241 // SetPolicy sets the specified policy in the application org group's config policy map. 242 // If an Organization policy already exists in current configuration, its value will be overwritten. 243 func (a *ApplicationOrg) SetPolicy(policyName string, policy Policy) error { 244 err := setPolicy(a.orgGroup, policyName, policy) 245 if err != nil { 246 return fmt.Errorf("failed to set policy '%s': %v", policyName, err) 247 } 248 249 return nil 250 } 251 252 // SetPolicies sets the specified policies in the application org group's config policy map. 253 // If the policies already exist in current configuration, the values will be replaced with new policies. 254 func (a *ApplicationOrg) SetPolicies(policies map[string]Policy) error { 255 err := setPolicies(a.orgGroup, policies) 256 if err != nil { 257 return fmt.Errorf("failed to set policies: %v", err) 258 } 259 260 return nil 261 } 262 263 // RemovePolicy removes an existing policy from an application organization. 264 func (a *ApplicationOrg) RemovePolicy(policyName string) error { 265 policies, err := a.Policies() 266 if err != nil { 267 return err 268 } 269 270 removePolicy(a.orgGroup, policyName, policies) 271 return nil 272 } 273 274 // AnchorPeers returns the list of anchor peers for an application org 275 // in the updated config. 276 func (a *ApplicationOrg) AnchorPeers() ([]Address, error) { 277 anchorPeerConfigValue, ok := a.orgGroup.Values[AnchorPeersKey] 278 if !ok { 279 return nil, nil 280 } 281 282 anchorPeersProto := &pb.AnchorPeers{} 283 284 err := proto.Unmarshal(anchorPeerConfigValue.Value, anchorPeersProto) 285 if err != nil { 286 return nil, fmt.Errorf("failed unmarshaling %s's anchor peer endpoints: %v", a.name, err) 287 } 288 289 if len(anchorPeersProto.AnchorPeers) == 0 { 290 return nil, nil 291 } 292 293 anchorPeers := []Address{} 294 for _, ap := range anchorPeersProto.AnchorPeers { 295 anchorPeers = append(anchorPeers, Address{ 296 Host: ap.Host, 297 Port: int(ap.Port), 298 }) 299 } 300 301 return anchorPeers, nil 302 } 303 304 // AddAnchorPeer adds an anchor peer to an application org's configuration 305 // in the updated config. 306 func (a *ApplicationOrg) AddAnchorPeer(newAnchorPeer Address) error { 307 anchorPeersProto := &pb.AnchorPeers{} 308 309 if anchorPeerConfigValue, ok := a.orgGroup.Values[AnchorPeersKey]; ok { 310 // Unmarshal existing anchor peers if the config value exists 311 err := proto.Unmarshal(anchorPeerConfigValue.Value, anchorPeersProto) 312 if err != nil { 313 return fmt.Errorf("failed unmarshaling anchor peer endpoints: %v", err) 314 } 315 } 316 317 // Persist existing anchor peers if found 318 anchorProtos := anchorPeersProto.AnchorPeers 319 320 for _, anchorPeer := range anchorProtos { 321 if anchorPeer.Host == newAnchorPeer.Host && anchorPeer.Port == int32(newAnchorPeer.Port) { 322 return nil 323 } 324 } 325 326 // Append new anchor peer to anchorProtos 327 anchorProtos = append(anchorProtos, &pb.AnchorPeer{ 328 Host: newAnchorPeer.Host, 329 Port: int32(newAnchorPeer.Port), 330 }) 331 332 // Add anchor peers config value back to application org 333 err := setValue(a.orgGroup, anchorPeersValue(anchorProtos), AdminsPolicyKey) 334 if err != nil { 335 return err 336 } 337 return nil 338 } 339 340 // RemoveAnchorPeer removes an anchor peer from an application org's configuration 341 // in the updated config. 342 func (a *ApplicationOrg) RemoveAnchorPeer(anchorPeerToRemove Address) error { 343 anchorPeersProto := &pb.AnchorPeers{} 344 345 if anchorPeerConfigValue, ok := a.orgGroup.Values[AnchorPeersKey]; ok { 346 // Unmarshal existing anchor peers if the config value exists 347 err := proto.Unmarshal(anchorPeerConfigValue.Value, anchorPeersProto) 348 if err != nil { 349 return fmt.Errorf("failed unmarshaling anchor peer endpoints for application org %s: %v", a.name, err) 350 } 351 } 352 353 existingAnchorPeers := anchorPeersProto.AnchorPeers[:0] 354 for _, anchorPeer := range anchorPeersProto.AnchorPeers { 355 if anchorPeer.Host != anchorPeerToRemove.Host || anchorPeer.Port != int32(anchorPeerToRemove.Port) { 356 existingAnchorPeers = append(existingAnchorPeers, anchorPeer) 357 358 // Add anchor peers config value back to application org 359 err := setValue(a.orgGroup, anchorPeersValue(existingAnchorPeers), AdminsPolicyKey) 360 if err != nil { 361 return fmt.Errorf("failed to remove anchor peer %v from org %s: %v", anchorPeerToRemove, a.name, err) 362 } 363 364 return nil 365 } 366 } 367 368 if len(existingAnchorPeers) == len(anchorPeersProto.AnchorPeers) { 369 return fmt.Errorf("could not find anchor peer %s:%d in application org %s", anchorPeerToRemove.Host, anchorPeerToRemove.Port, a.name) 370 } 371 372 // Add anchor peers config value back to application org 373 err := setValue(a.orgGroup, anchorPeersValue(existingAnchorPeers), AdminsPolicyKey) 374 if err != nil { 375 return fmt.Errorf("failed to remove anchor peer %v from org %s: %v", anchorPeerToRemove, a.name, err) 376 } 377 378 return nil 379 } 380 381 // ACLs returns a map of ACLS for given config application. 382 func (a *ApplicationGroup) ACLs() (map[string]string, error) { 383 aclConfigValue, ok := a.applicationGroup.Values[ACLsKey] 384 if !ok { 385 return nil, nil 386 } 387 388 aclProtos := &pb.ACLs{} 389 390 err := proto.Unmarshal(aclConfigValue.Value, aclProtos) 391 if err != nil { 392 return nil, fmt.Errorf("unmarshaling %s: %v", ACLsKey, err) 393 } 394 395 retACLs := map[string]string{} 396 for apiResource, policyRef := range aclProtos.Acls { 397 retACLs[apiResource] = policyRef.PolicyRef 398 } 399 400 return retACLs, nil 401 } 402 403 // SetACLs sets ACLS to an existing channel config application. 404 // If an ACL already exists in current configuration, it will be replaced with new ACL. 405 func (a *ApplicationGroup) SetACLs(acls map[string]string) error { 406 err := setValue(a.applicationGroup, aclValues(acls), AdminsPolicyKey) 407 if err != nil { 408 return err 409 } 410 411 return nil 412 } 413 414 // RemoveACLs a list of ACLs from given channel config application. 415 // Specifying acls that do not exist in the application ConfigGroup of the channel config will not return a error. 416 // Removal will panic if application group does not exist. 417 func (a *ApplicationGroup) RemoveACLs(acls []string) error { 418 configACLs, err := a.ACLs() 419 if err != nil { 420 return err 421 } 422 423 for _, acl := range acls { 424 delete(configACLs, acl) 425 } 426 427 err = setValue(a.applicationGroup, aclValues(configACLs), AdminsPolicyKey) 428 if err != nil { 429 return err 430 } 431 432 return nil 433 } 434 435 // SetMSP updates the MSP config for the specified application 436 // org group. 437 func (a *ApplicationOrg) SetMSP(updatedMSP MSP) error { 438 currentMSP, err := a.MSP().Configuration() 439 if err != nil { 440 return fmt.Errorf("retrieving msp: %v", err) 441 } 442 443 if currentMSP.Name != updatedMSP.Name { 444 return errors.New("MSP name cannot be changed") 445 } 446 447 err = updatedMSP.validateCACerts() 448 if err != nil { 449 return err 450 } 451 452 err = a.setMSPConfig(updatedMSP) 453 if err != nil { 454 return err 455 } 456 457 return nil 458 } 459 460 func (a *ApplicationOrg) setMSPConfig(updatedMSP MSP) error { 461 mspConfig, err := newMSPConfig(updatedMSP) 462 if err != nil { 463 return fmt.Errorf("new msp config: %v", err) 464 } 465 466 err = setValue(a.orgGroup, mspValue(mspConfig), AdminsPolicyKey) 467 if err != nil { 468 return err 469 } 470 471 return nil 472 } 473 474 // newApplicationGroupTemplate returns the application component of the channel 475 // configuration with only the names of the application organizations. 476 // By default, it sets the mod_policy of all elements to "Admins". 477 func newApplicationGroupTemplate(application Application) (*cb.ConfigGroup, error) { 478 var err error 479 480 applicationGroup := newConfigGroup() 481 applicationGroup.ModPolicy = AdminsPolicyKey 482 483 if application.ModPolicy != "" { 484 applicationGroup.ModPolicy = application.ModPolicy 485 } 486 487 if err = setPolicies(applicationGroup, application.Policies); err != nil { 488 return nil, err 489 } 490 491 if len(application.ACLs) > 0 { 492 err = setValue(applicationGroup, aclValues(application.ACLs), AdminsPolicyKey) 493 if err != nil { 494 return nil, err 495 } 496 } 497 498 if len(application.Capabilities) > 0 { 499 err = setValue(applicationGroup, capabilitiesValue(application.Capabilities), AdminsPolicyKey) 500 if err != nil { 501 return nil, err 502 } 503 } 504 505 for _, org := range application.Organizations { 506 applicationGroup.Groups[org.Name] = newConfigGroup() 507 } 508 509 return applicationGroup, nil 510 } 511 512 // newApplicationGroup returns the application component of the channel 513 // configuration with the entire configuration for application organizations. 514 // By default, it sets the mod_policy of all elements to "Admins". 515 func newApplicationGroup(application Application) (*cb.ConfigGroup, error) { 516 applicationGroup, err := newApplicationGroupTemplate(application) 517 if err != nil { 518 return nil, err 519 } 520 521 for _, org := range application.Organizations { 522 applicationGroup.Groups[org.Name], err = newOrgConfigGroup(org) 523 if err != nil { 524 return nil, fmt.Errorf("org group '%s': %v", org.Name, err) 525 } 526 } 527 528 return applicationGroup, nil 529 } 530 531 // aclValues returns the config definition for an application's resources based ACL definitions. 532 // It is a value for the /Channel/Application/. 533 func aclValues(acls map[string]string) *standardConfigValue { 534 a := &pb.ACLs{ 535 Acls: make(map[string]*pb.APIResource), 536 } 537 538 for apiResource, policyRef := range acls { 539 a.Acls[apiResource] = &pb.APIResource{PolicyRef: policyRef} 540 } 541 542 return &standardConfigValue{ 543 key: ACLsKey, 544 value: a, 545 } 546 } 547 548 // anchorPeersValue returns the config definition for an org's anchor peers. 549 // It is a value for the /Channel/Application/*. 550 func anchorPeersValue(anchorPeers []*pb.AnchorPeer) *standardConfigValue { 551 return &standardConfigValue{ 552 key: AnchorPeersKey, 553 value: &pb.AnchorPeers{AnchorPeers: anchorPeers}, 554 } 555 }