github.com/Axway/agent-sdk@v1.1.101/pkg/config/centralconfig.go (about) 1 package config 2 3 import ( 4 "errors" 5 "fmt" 6 "net/url" 7 "os" 8 "strings" 9 "time" 10 11 v1 "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/api/v1" 12 mv1 "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1" 13 "github.com/Axway/agent-sdk/pkg/cmd/properties" 14 "github.com/Axway/agent-sdk/pkg/util/exception" 15 "github.com/Axway/agent-sdk/pkg/util/log" 16 "github.com/gorhill/cronexpr" 17 ) 18 19 const urlCutSet = " /" 20 21 type Region int 22 23 const ( 24 US Region = iota + 1 25 EU 26 AP 27 ) 28 29 var regionNamesMap = map[Region]string{ 30 US: "US", 31 EU: "EU", 32 AP: "AP", 33 } 34 35 var nameToRegionMap = map[string]Region{ 36 "US": US, 37 "EU": EU, 38 "AP": AP, 39 } 40 41 func (r Region) ToString() string { 42 return regionNamesMap[r] 43 } 44 45 type regionalSettings struct { 46 SingleURL string 47 CentralURL string 48 AuthURL string 49 PlatformURL string 50 TraceabilityHost string 51 Deployment string 52 } 53 54 var regionalSettingsMap = map[Region]regionalSettings{ 55 US: { 56 SingleURL: "https://ingestion.platform.axway.com", 57 CentralURL: "https://apicentral.axway.com", 58 AuthURL: "https://login.axway.com/auth", 59 PlatformURL: "https://platform.axway.com", 60 TraceabilityHost: "ingestion.datasearch.axway.com:5044", 61 Deployment: "prod", 62 }, 63 EU: { 64 SingleURL: "https://ingestion-eu.platform.axway.com", 65 CentralURL: "https://central.eu-fr.axway.com", 66 AuthURL: "https://login.axway.com/auth", 67 PlatformURL: "https://platform.axway.com", 68 TraceabilityHost: "ingestion.visibility.eu-fr.axway.com:5044", 69 Deployment: "prod-eu", 70 }, 71 AP: { 72 SingleURL: "https://ingestion-ap-sg.platform.axway.com", 73 CentralURL: "https://central.ap-sg.axway.com", 74 AuthURL: "https://login.axway.com/auth", 75 PlatformURL: "https://platform.axway.com", 76 TraceabilityHost: "ingestion.visibility.ap-sg.axway.com:5044", 77 Deployment: "prod-ap", 78 }, 79 } 80 81 // AgentType - Defines the type of agent 82 type AgentType int 83 84 const ( 85 // DiscoveryAgent - Type definition for discovery agent 86 DiscoveryAgent AgentType = iota + 1 87 // TraceabilityAgent - Type definition for traceability agent 88 TraceabilityAgent 89 // GovernanceAgent - Type definition for governance agent 90 GovernanceAgent 91 // GenericService - Type for a generic service 92 GenericService 93 ) 94 95 var agentTypeNamesMap = map[AgentType]string{ 96 DiscoveryAgent: "discoveryagent", 97 TraceabilityAgent: "traceabilityagent", 98 GovernanceAgent: "governanceagent", 99 } 100 101 var agentTypeShortNamesMap = map[AgentType]string{ 102 DiscoveryAgent: "da", 103 TraceabilityAgent: "ta", 104 GovernanceAgent: "ga", 105 } 106 107 func (agentType AgentType) ToString() string { 108 return agentTypeNamesMap[agentType] 109 } 110 111 func (agentType AgentType) ToShortString() string { 112 return agentTypeShortNamesMap[agentType] 113 } 114 115 // subscription approval types 116 const ( 117 ManualApproval string = "manual" 118 AutoApproval string = "auto" 119 WebhookApproval string = "webhook" 120 ) 121 122 // AgentTypeName - Holds the name Agent type 123 var AgentTypeName string 124 125 // AgentDisplayName - Holds the name Agent name for displaying in version command or elsewhere 126 var AgentDisplayName string 127 128 // AgentVersion - Holds the version of agent 129 var AgentVersion string 130 131 // AgentLatestVersion - Holds the latest version of the agent 132 var AgentLatestVersion string 133 134 // AgentDataPlaneType - Holds the data plane type of agent 135 var AgentDataPlaneType string 136 137 // SDKVersion - Holds the version of SDK 138 var SDKVersion string 139 140 // IConfigValidator - Interface to be implemented for config validation by agent 141 type IConfigValidator interface { 142 ValidateCfg() error 143 } 144 145 // IResourceConfigCallback - Interface to be implemented by configs to apply API Server resource for agent 146 type IResourceConfigCallback interface { 147 ApplyResources(agentResource *v1.ResourceInstance) error 148 } 149 150 // CentralConfig - Interface to get central Config 151 type CentralConfig interface { 152 GetAgentType() AgentType 153 GetRegion() Region 154 GetTenantID() string 155 GetAPICDeployment() string 156 GetEnvironmentID() string 157 SetEnvironmentID(environmentID string) 158 IsAxwayManaged() bool 159 SetAxwayManaged(isAxwayManaged bool) 160 GetEnvironmentName() string 161 GetAgentName() string 162 GetTeamName() string 163 GetTeamID() string 164 SetTeamID(teamID string) 165 GetURL() string 166 GetTraceabilityHost() string 167 GetPlatformURL() string 168 GetAPIServerURL() string 169 GetEnvironmentURL() string 170 GetEnvironmentACLsURL() string 171 GetServicesURL() string 172 GetRevisionsURL() string 173 GetInstancesURL() string 174 DeleteServicesURL() string 175 GetAPIServerAccessRequestDefinitionURL() string 176 GetAPIServerSecretsURL() string 177 GetAccessRequestsURL() string 178 GetAccessRequestURL(string) string 179 GetAccessRequestStateURL(string) string 180 GetAuthConfig() AuthConfig 181 GetTLSConfig() TLSConfig 182 GetTagsToPublish() string 183 GetProxyURL() string 184 GetPollInterval() time.Duration 185 GetReportActivityFrequency() time.Duration 186 GetAPIValidationCronSchedule() string 187 GetJobExecutionTimeout() time.Duration 188 GetClientTimeout() time.Duration 189 GetPageSize() int 190 GetAPIServiceRevisionPattern() string 191 GetAppendEnvironmentToTitle() bool 192 GetUsageReportingConfig() UsageReportingConfig 193 GetMetricReportingConfig() MetricReportingConfig 194 IsUsingGRPC() bool 195 GetGRPCHost() string 196 GetGRPCPort() int 197 IsGRPCInsecure() bool 198 GetCacheStoragePath() string 199 GetCacheStorageInterval() time.Duration 200 GetSingleURL() string 201 GetMigrationSettings() MigrationConfig 202 GetWatchResourceFilters() []ResourceFilter 203 SetWatchResourceFilters([]ResourceFilter) error 204 GetCredentialConfig() CredentialConfig 205 } 206 207 // CentralConfiguration - Structure to hold the central config 208 type CentralConfiguration struct { 209 CentralConfig 210 IConfigValidator 211 AgentType AgentType 212 RegionSettings regionalSettings 213 Region Region `config:"region"` 214 TenantID string `config:"organizationID"` 215 TeamName string `config:"team"` 216 APICDeployment string `config:"deployment"` 217 Environment string `config:"environment"` 218 EnvironmentID string `config:"environmentID"` 219 AgentName string `config:"agentName"` 220 URL string `config:"url"` 221 SingleURL string `config:"platformSingleURL"` 222 PlatformURL string `config:"platformURL"` 223 APIServerVersion string `config:"apiServerVersion"` 224 TagsToPublish string `config:"additionalTags"` 225 AppendEnvironmentToTitle bool `config:"appendEnvironmentToTitle"` 226 MigrationSettings MigrationConfig `config:"migration"` 227 Auth AuthConfig `config:"auth"` 228 TLS TLSConfig `config:"ssl"` 229 PollInterval time.Duration `config:"pollInterval"` 230 ReportActivityFrequency time.Duration `config:"reportActivityFrequency"` 231 ClientTimeout time.Duration `config:"clientTimeout"` 232 PageSize int `config:"pageSize"` 233 APIValidationCronSchedule string `config:"apiValidationCronSchedule"` 234 APIServiceRevisionPattern string `config:"apiServiceRevisionPattern"` 235 ProxyURL string `config:"proxyUrl"` 236 UsageReporting UsageReportingConfig `config:"usageReporting"` 237 MetricReporting MetricReportingConfig `config:"metricReporting"` 238 GRPCCfg GRPCConfig `config:"grpc"` 239 CacheStoragePath string `config:"cacheStoragePath"` 240 CacheStorageInterval time.Duration `config:"cacheStorageInterval"` 241 CredentialConfig CredentialConfig `config:"credential"` 242 JobExecutionTimeout time.Duration 243 environmentID string 244 teamID string 245 isSingleURLSet bool 246 isRegionSet bool 247 isAxwayManaged bool 248 WatchResourceFilters []ResourceFilter 249 } 250 251 // GRPCConfig - Represents the grpc config 252 type GRPCConfig struct { 253 Enabled bool `config:"enabled"` 254 Host string `config:"host"` 255 Port int `config:"port"` 256 Insecure bool `config:"insecure"` 257 } 258 259 // NewCentralConfig - Creates the default central config 260 func NewCentralConfig(agentType AgentType) CentralConfig { 261 platformURL := "https://platform.axway.com" 262 return &CentralConfiguration{ 263 AgentType: agentType, 264 Region: US, 265 TeamName: "", 266 APIServerVersion: "v1alpha1", 267 Auth: newAuthConfig(), 268 TLS: NewTLSConfig(), 269 PollInterval: 60 * time.Second, 270 ClientTimeout: 60 * time.Second, 271 PageSize: 100, 272 PlatformURL: platformURL, 273 SingleURL: "", 274 AppendEnvironmentToTitle: true, 275 ReportActivityFrequency: 5 * time.Minute, 276 APIValidationCronSchedule: "@daily", 277 UsageReporting: NewUsageReporting(platformURL), 278 MetricReporting: NewMetricReporting(), 279 JobExecutionTimeout: 5 * time.Minute, 280 CacheStorageInterval: 10 * time.Second, 281 GRPCCfg: GRPCConfig{ 282 Enabled: true, 283 }, 284 MigrationSettings: newMigrationConfig(), 285 CredentialConfig: newCredentialConfig(), 286 } 287 } 288 289 // NewTestCentralConfig - Creates the default central config 290 func NewTestCentralConfig(agentType AgentType) CentralConfig { 291 config := NewCentralConfig(agentType).(*CentralConfiguration) 292 config.TenantID = "1234567890" 293 config.Region = US 294 config.URL = "https://central.com" 295 config.PlatformURL = "https://platform.axway.com" 296 config.Environment = "environment" 297 config.environmentID = "env-id" 298 config.Auth = newTestAuthConfig() 299 config.MigrationSettings = newTestMigrationConfig() 300 if agentType == TraceabilityAgent { 301 config.APICDeployment = "deployment" 302 } 303 return config 304 } 305 306 // GetPlatformURL - Returns the central base URL 307 func (c *CentralConfiguration) GetPlatformURL() string { 308 if c.PlatformURL == "" { 309 return c.RegionSettings.PlatformURL 310 } 311 return c.PlatformURL 312 } 313 314 // GetAgentType - Returns the agent type 315 func (c *CentralConfiguration) GetAgentType() AgentType { 316 return c.AgentType 317 } 318 319 // GetRegion - Returns the region 320 func (c *CentralConfiguration) GetRegion() Region { 321 return c.Region 322 } 323 324 // GetTenantID - Returns the tenant ID 325 func (c *CentralConfiguration) GetTenantID() string { 326 return c.TenantID 327 } 328 329 // GetAPICDeployment - Returns the Central deployment type 'prod', 'preprod', team ('beano') 330 func (c *CentralConfiguration) GetAPICDeployment() string { 331 if c.APICDeployment == "" { 332 return c.RegionSettings.Deployment 333 } 334 return c.APICDeployment 335 } 336 337 // GetEnvironmentID - Returns the environment ID 338 func (c *CentralConfiguration) GetEnvironmentID() string { 339 return c.environmentID 340 } 341 342 // SetEnvironmentID - Sets the environment ID 343 func (c *CentralConfiguration) SetEnvironmentID(environmentID string) { 344 c.environmentID = environmentID 345 } 346 347 // IsAxwayManaged - Returns the environment ID 348 func (c *CentralConfiguration) IsAxwayManaged() bool { 349 return c.isAxwayManaged 350 } 351 352 // SetAxwayManaged - Sets the environment ID 353 func (c *CentralConfiguration) SetAxwayManaged(isManaged bool) { 354 c.isAxwayManaged = isManaged 355 } 356 357 // GetEnvironmentName - Returns the environment name 358 func (c *CentralConfiguration) GetEnvironmentName() string { 359 return c.Environment 360 } 361 362 // GetAgentName - Returns the agent name 363 func (c *CentralConfiguration) GetAgentName() string { 364 return c.AgentName 365 } 366 367 // GetTeamName - Returns the team name 368 func (c *CentralConfiguration) GetTeamName() string { 369 return c.TeamName 370 } 371 372 // GetTeamID - Returns the team ID 373 func (c *CentralConfiguration) GetTeamID() string { 374 return c.teamID 375 } 376 377 // SetTeamID - Sets the team ID 378 func (c *CentralConfiguration) SetTeamID(teamID string) { 379 c.teamID = teamID 380 } 381 382 // GetURL - Returns the central base URL 383 func (c *CentralConfiguration) GetURL() string { 384 if c.URL == "" { 385 return c.RegionSettings.CentralURL 386 } 387 return c.URL 388 } 389 390 // GetTraceabilityHost - Returns the central traceability host 391 func (c *CentralConfiguration) GetTraceabilityHost() string { 392 if c.isRegionSet { 393 return c.RegionSettings.TraceabilityHost 394 } 395 return "" 396 } 397 398 // GetProxyURL - Returns the central Proxy URL 399 func (c *CentralConfiguration) GetProxyURL() string { 400 return c.ProxyURL 401 } 402 403 // GetAccessRequestsURL - Returns the accessrequest URL for access request API 404 func (c *CentralConfiguration) GetAccessRequestsURL() string { 405 return c.GetEnvironmentURL() + "/accessrequests" 406 } 407 408 // GetAPIServerURL - Returns the base path for the API server 409 func (c *CentralConfiguration) GetAPIServerURL() string { 410 return c.GetURL() + "/apis/management/" + c.APIServerVersion + "/environments/" 411 } 412 413 // GetEnvironmentURL - Returns the APIServer URL for services API 414 func (c *CentralConfiguration) GetEnvironmentURL() string { 415 return c.GetAPIServerURL() + c.Environment 416 } 417 418 // GetEnvironmentACLsURL - Returns the APIServer URL for ACLs in Environments 419 func (c *CentralConfiguration) GetEnvironmentACLsURL() string { 420 return c.GetEnvironmentURL() + "/accesscontrollists" 421 } 422 423 // GetServicesURL - Returns the APIServer URL for services API 424 func (c *CentralConfiguration) GetServicesURL() string { 425 return c.GetEnvironmentURL() + "/apiservices" 426 } 427 428 // GetRevisionsURL - Returns the APIServer URL for services API revisions 429 func (c *CentralConfiguration) GetRevisionsURL() string { 430 return c.GetEnvironmentURL() + "/apiservicerevisions" 431 } 432 433 // GetInstancesURL - Returns the APIServer URL for services API instances 434 func (c *CentralConfiguration) GetInstancesURL() string { 435 return c.GetEnvironmentURL() + "/apiserviceinstances" 436 } 437 438 // DeleteServicesURL - Returns the APIServer URL for services API instances 439 func (c *CentralConfiguration) DeleteServicesURL() string { 440 return c.GetEnvironmentURL() + "/apiservices" 441 } 442 443 // GetAPIServerAccessRequestDefinitionURL - Returns the APIServer URL for access request definitions 444 func (c *CentralConfiguration) GetAPIServerAccessRequestDefinitionURL() string { 445 return c.GetEnvironmentURL() + "/accessrequestdefinitions" 446 } 447 448 // GetAPIServerSecretsURL - Returns the APIServer URL for secrets 449 func (c *CentralConfiguration) GetAPIServerSecretsURL() string { 450 return c.GetEnvironmentURL() + "/secrets" 451 } 452 453 // GetAccessRequestURL - Returns the access request URL for catalog item subscription states 454 func (c *CentralConfiguration) GetAccessRequestURL(accessRequestName string) string { 455 return fmt.Sprintf("%s/%s", c.GetAccessRequestsURL(), accessRequestName) 456 } 457 458 // GetAccessRequestStateURL - Returns the access request URL to update the state 459 func (c *CentralConfiguration) GetAccessRequestStateURL(accessRequestName string) string { 460 return fmt.Sprintf("%s/state", c.GetAccessRequestURL(accessRequestName)) 461 } 462 463 // GetAuthConfig - Returns the Auth Config 464 func (c *CentralConfiguration) GetAuthConfig() AuthConfig { 465 return c.Auth 466 } 467 468 // GetMigrationSettings - Returns the Migration Config 469 func (c *CentralConfiguration) GetMigrationSettings() MigrationConfig { 470 return c.MigrationSettings 471 } 472 473 // GetTLSConfig - Returns the TLS Config 474 func (c *CentralConfiguration) GetTLSConfig() TLSConfig { 475 return c.TLS 476 } 477 478 // GetTagsToPublish - Returns tags to publish 479 func (c *CentralConfiguration) GetTagsToPublish() string { 480 return c.TagsToPublish 481 } 482 483 // GetPollInterval - Returns the interval for polling subscriptions 484 func (c *CentralConfiguration) GetPollInterval() time.Duration { 485 return c.PollInterval 486 } 487 488 // GetReportActivityFrequency - Returns the interval between running periodic status updater 489 func (c *CentralConfiguration) GetReportActivityFrequency() time.Duration { 490 return c.ReportActivityFrequency 491 } 492 493 // GetAPIValidationCronSchedule - Returns the cron schedule running the api validator 494 func (c *CentralConfiguration) GetAPIValidationCronSchedule() string { 495 return c.APIValidationCronSchedule 496 } 497 498 // GetJobExecutionTimeout - Returns the max time a job execution can run before considered failed 499 func (c *CentralConfiguration) GetJobExecutionTimeout() time.Duration { 500 return c.JobExecutionTimeout 501 } 502 503 // GetClientTimeout - Returns the interval for http client timeouts 504 func (c *CentralConfiguration) GetClientTimeout() time.Duration { 505 return c.ClientTimeout 506 } 507 508 // GetPageSize - Returns the page size for api server calls 509 func (c *CentralConfiguration) GetPageSize() int { 510 return c.PageSize 511 } 512 513 // GetAPIServiceRevisionPattern - Returns the naming pattern for APIServiceRevition title 514 func (c *CentralConfiguration) GetAPIServiceRevisionPattern() string { 515 return c.APIServiceRevisionPattern 516 } 517 518 // GetAppendEnvironmentToTitle - Returns the value of append environment name to title attribute 519 func (c *CentralConfiguration) GetAppendEnvironmentToTitle() bool { 520 return c.AppendEnvironmentToTitle 521 } 522 523 // GetUsageReportingConfig - 524 func (c *CentralConfiguration) GetUsageReportingConfig() UsageReportingConfig { 525 // Some paths in DA are checking usage reporting . So return an empty usage reporting config if nil 526 // Find All References to see DA scenarios checking for this config 527 if c.UsageReporting == nil { 528 return NewUsageReporting(c.GetPlatformURL()) 529 } 530 return c.UsageReporting 531 } 532 533 // GetMetricReportingConfig - 534 func (c *CentralConfiguration) GetMetricReportingConfig() MetricReportingConfig { 535 // Some paths in DA are checking usage reporting . So return an empty usage reporting config if nil 536 // Find All References to see DA scenarios checking for this config 537 if c.MetricReporting == nil { 538 return NewMetricReporting() 539 } 540 return c.MetricReporting 541 } 542 543 // GetCredentialConfig - 544 func (c *CentralConfiguration) GetCredentialConfig() CredentialConfig { 545 return c.CredentialConfig 546 } 547 548 // IsUsingGRPC - 549 func (c *CentralConfiguration) IsUsingGRPC() bool { 550 return c.GRPCCfg.Enabled 551 } 552 553 // GetGRPCHost - 554 func (c *CentralConfiguration) GetGRPCHost() string { 555 return c.GRPCCfg.Host 556 } 557 558 // GetGRPCPort - 559 func (c *CentralConfiguration) GetGRPCPort() int { 560 return c.GRPCCfg.Port 561 } 562 563 // IsGRPCInsecure - 564 func (c *CentralConfiguration) IsGRPCInsecure() bool { 565 return c.GRPCCfg.Insecure 566 } 567 568 // GetCacheStoragePath - 569 func (c *CentralConfiguration) GetCacheStoragePath() string { 570 return c.CacheStoragePath 571 } 572 573 // GetCacheStorageInterval - 574 func (c *CentralConfiguration) GetCacheStorageInterval() time.Duration { 575 return c.CacheStorageInterval 576 } 577 578 // GetSingleURL - Returns the Alternate base URL 579 func (c *CentralConfiguration) GetSingleURL() string { 580 if c.SingleURL == "" && !c.isSingleURLSet { 581 if c.isRegionSet { 582 return c.RegionSettings.SingleURL 583 } 584 585 } 586 return c.SingleURL 587 } 588 589 // GetWatchResourceFilters - returns the custom watch filter config 590 func (c *CentralConfiguration) GetWatchResourceFilters() []ResourceFilter { 591 if c.WatchResourceFilters == nil { 592 c.WatchResourceFilters = make([]ResourceFilter, 0) 593 } 594 return c.WatchResourceFilters 595 } 596 597 // SetWatchResourceFilters - sets the custom watch filter config 598 func (c *CentralConfiguration) SetWatchResourceFilters(filters []ResourceFilter) error { 599 c.WatchResourceFilters = make([]ResourceFilter, 0) 600 for _, filter := range filters { 601 if filter.Group == "" || filter.Kind == "" { 602 return errors.New("invalid watch filter configuration, group and kind are required") 603 } 604 605 if filter.Name == "" { 606 filter.Name = "*" 607 } 608 if len(filter.EventTypes) == 0 { 609 filter.EventTypes = []ResourceEventType{ResourceEventCreated, ResourceEventUpdated, ResourceEventDeleted} 610 } 611 612 if filter.Scope == nil { 613 filter.Scope = &ResourceScope{ 614 Kind: mv1.EnvironmentGVK().Kind, 615 Name: c.GetEnvironmentName(), 616 } 617 } else { 618 if filter.Scope.Kind == "" || filter.Scope.Name == "" { 619 return errors.New("invalid watch filter configuration, scope kind and name are required") 620 } 621 } 622 623 c.WatchResourceFilters = append(c.WatchResourceFilters, filter) 624 } 625 626 return nil 627 } 628 629 const ( 630 pathRegion = "central.region" 631 pathTenantID = "central.organizationID" 632 pathURL = "central.url" 633 pathPlatformURL = "central.platformURL" 634 pathAuthPrivateKey = "central.auth.privateKey" 635 pathAuthPublicKey = "central.auth.publicKey" 636 pathAuthKeyPassword = "central.auth.keyPassword" 637 pathAuthURL = "central.auth.url" 638 pathSingleURL = "central.singleURL" 639 pathAuthRealm = "central.auth.realm" 640 pathAuthClientID = "central.auth.clientId" 641 pathAuthTimeout = "central.auth.timeout" 642 pathSSLNextProtos = "central.ssl.nextProtos" 643 pathSSLInsecureSkipVerify = "central.ssl.insecureSkipVerify" 644 pathSSLCipherSuites = "central.ssl.cipherSuites" 645 pathSSLMinVersion = "central.ssl.minVersion" 646 pathSSLMaxVersion = "central.ssl.maxVersion" 647 pathEnvironment = "central.environment" 648 pathEnvironmentID = "central.environmentID" 649 pathAgentName = "central.agentName" 650 pathDeployment = "central.deployment" 651 pathMode = "central.mode" 652 pathTeam = "central.team" 653 pathPollInterval = "central.pollInterval" 654 pathReportActivityFrequency = "central.reportActivityFrequency" 655 pathClientTimeout = "central.clientTimeout" 656 pathPageSize = "central.pageSize" 657 pathAPIServiceRevisionPattern = "central.apiServiceRevisionPattern" 658 pathProxyURL = "central.proxyUrl" 659 pathAPIServerVersion = "central.apiServerVersion" 660 pathAdditionalTags = "central.additionalTags" 661 pathAppendEnvironmentToTitle = "central.appendEnvironmentToTitle" 662 pathAPIValidationCronSchedule = "central.apiValidationCronSchedule" 663 pathJobTimeout = "central.jobTimeout" 664 pathGRPCEnabled = "central.grpc.enabled" 665 pathGRPCHost = "central.grpc.host" 666 pathGRPCPort = "central.grpc.port" 667 pathGRPCInsecure = "central.grpc.insecure" 668 pathCacheStoragePath = "central.cacheStoragePath" 669 pathCacheStorageInterval = "central.cacheStorageInterval" 670 pathCredentialsOAuthMethods = "central.credentials.oauthMethods" 671 ) 672 673 // ValidateCfg - Validates the config, implementing IConfigInterface 674 func (c *CentralConfiguration) ValidateCfg() (err error) { 675 exception.Block{ 676 Try: func() { 677 if supportsTraceability(c.AgentType) && c.GetUsageReportingConfig().IsOfflineMode() { 678 // only validate certain things when a traceability agent is in offline mode 679 c.validateOfflineConfig() 680 c.GetUsageReportingConfig().Validate() 681 return 682 } 683 c.validateConfig() 684 c.Auth.validate() 685 686 // Check that platform service account is used with market place provisioning 687 if strings.HasPrefix(c.Auth.GetClientID(), "DOSA_") { 688 exception.Throw(ErrServiceAccount) 689 } 690 691 if supportsTraceability(c.AgentType) { 692 c.GetMetricReportingConfig().Validate() 693 c.GetUsageReportingConfig().Validate() 694 } 695 }, 696 Catch: func(e error) { 697 err = e 698 }, 699 }.Do() 700 701 return 702 } 703 704 func (c *CentralConfiguration) validateConfig() { 705 if c.GetTenantID() == "" { 706 exception.Throw(ErrBadConfig.FormatError(pathTenantID)) 707 } 708 709 c.validateURL(c.GetURL(), pathURL, true) 710 711 c.validateURL(c.GetPlatformURL(), pathPlatformURL, true) 712 713 if c.GetSingleURL() != "" { 714 c.validateURL(c.GetSingleURL(), pathSingleURL, true) 715 } 716 717 // proxyURL 718 c.validateURL(c.GetProxyURL(), pathProxyURL, false) 719 720 if supportsTraceability(c.AgentType) { 721 c.validateTraceabilityAgentConfig() 722 } else { 723 c.validateEnvironmentConfig() 724 c.validateDiscoveryAgentConfig() 725 } 726 727 if c.GetReportActivityFrequency() <= 0 { 728 exception.Throw(ErrBadConfig.FormatError(pathReportActivityFrequency)) 729 } 730 731 cron, err := cronexpr.Parse(c.GetAPIValidationCronSchedule()) 732 if err != nil { 733 exception.Throw(ErrBadConfig.FormatError(pathAPIValidationCronSchedule)) 734 } 735 checks := 5 736 nextRuns := cron.NextN(time.Now(), uint(checks)) 737 if len(nextRuns) != checks { 738 exception.Throw(ErrBadConfig.FormatError(pathAPIValidationCronSchedule)) 739 } 740 for i := 1; i < checks-1; i++ { 741 delta := nextRuns[i].Sub(nextRuns[i-1]) 742 if delta < time.Hour { 743 log.Tracef("%s must be at least 1 hour apart", pathAPIValidationCronSchedule) 744 exception.Throw(ErrBadConfig.FormatError(pathAPIValidationCronSchedule)) 745 } 746 } 747 748 if c.GetClientTimeout() <= 0 { 749 exception.Throw(ErrBadConfig.FormatError(pathClientTimeout)) 750 } 751 if c.GetJobExecutionTimeout() < 0 { 752 exception.Throw(ErrBadConfig.FormatError(pathJobTimeout)) 753 } 754 755 } 756 757 func (c *CentralConfiguration) validateURL(urlString, configPath string, isURLRequired bool) { 758 if isURLRequired && urlString == "" { 759 exception.Throw(ErrBadConfig.FormatError(configPath)) 760 } 761 if urlString != "" { 762 if _, err := url.ParseRequestURI(urlString); err != nil { 763 exception.Throw(ErrBadConfig.FormatError(configPath)) 764 } 765 } 766 } 767 768 func (c *CentralConfiguration) validateDiscoveryAgentConfig() { 769 if c.GetPollInterval() <= 0 { 770 exception.Throw(ErrBadConfig.FormatError(pathPollInterval)) 771 } 772 } 773 774 func (c *CentralConfiguration) validateEnvironmentConfig() { 775 if c.GetEnvironmentName() == "" { 776 exception.Throw(ErrBadConfig.FormatError(pathEnvironment)) 777 } 778 779 if c.APIServerVersion == "" { 780 exception.Throw(ErrBadConfig.FormatError(pathAPIServerVersion)) 781 } 782 } 783 func (c *CentralConfiguration) validateTraceabilityAgentConfig() { 784 if c.GetAPICDeployment() == "" { 785 exception.Throw(ErrBadConfig.FormatError(pathDeployment)) 786 } 787 if c.GetEnvironmentName() == "" { 788 exception.Throw(ErrBadConfig.FormatError(pathEnvironment)) 789 } 790 } 791 792 func (c *CentralConfiguration) validateOfflineConfig() { 793 // validate environment ID 794 c.SetEnvironmentID(c.EnvironmentID) 795 if c.GetEnvironmentID() == "" { 796 exception.Throw(ErrBadConfig.FormatError(pathEnvironmentID)) 797 } 798 } 799 800 // AddCentralConfigProperties - Adds the command properties needed for Central Config 801 func AddCentralConfigProperties(props properties.Properties, agentType AgentType) { 802 props.AddStringProperty(pathTenantID, "", "Tenant ID for the owner of the environment") 803 props.AddStringProperty(pathURL, "", "URL of Amplify Central") 804 props.AddStringProperty(pathTeam, "", "Team name for creating catalog") 805 props.AddStringProperty(pathPlatformURL, "", "URL of the platform") 806 props.AddStringProperty(pathSingleURL, "", "Alternate Connection for Agent if using static IP") 807 props.AddStringProperty(pathAuthPrivateKey, "/etc/private_key.pem", "Path to the private key for Amplify Central Authentication") 808 props.AddStringProperty(pathAuthPublicKey, "/etc/public_key", "Path to the public key for Amplify Central Authentication") 809 props.AddStringProperty(pathAuthKeyPassword, "", "Path to the password file required by the private key for Amplify Central Authentication") 810 props.AddStringProperty(pathAuthURL, "", "Amplify Central authentication URL") 811 props.AddStringProperty(pathAuthRealm, "Broker", "Amplify Central authentication Realm") 812 props.AddStringProperty(pathAuthClientID, "", "Client ID for the service account") 813 props.AddDurationProperty(pathAuthTimeout, 10*time.Second, "Timeout waiting for AxwayID response", properties.WithLowerLimit(10*time.Second)) 814 // ssl properties and command flags 815 props.AddStringSliceProperty(pathSSLNextProtos, []string{}, "List of supported application level protocols, comma separated") 816 props.AddBoolProperty(pathSSLInsecureSkipVerify, false, "Controls whether a client verifies the server's certificate chain and host name") 817 props.AddStringSliceProperty(pathSSLCipherSuites, TLSDefaultCipherSuitesStringSlice(), "List of supported cipher suites, comma separated") 818 props.AddStringProperty(pathSSLMinVersion, TLSDefaultMinVersionString(), "Minimum acceptable SSL/TLS protocol version") 819 props.AddStringProperty(pathSSLMaxVersion, "0", "Maximum acceptable SSL/TLS protocol version") 820 props.AddStringProperty(pathEnvironment, "", "The Environment that the APIs will be associated with in Amplify Central") 821 props.AddStringProperty(pathAgentName, "", "The name of the asociated agent resource in Amplify Central") 822 props.AddStringProperty(pathProxyURL, "", "The Proxy URL to use for communication to Amplify Central") 823 props.AddDurationProperty(pathPollInterval, 60*time.Second, "The time interval at which the central will be polled for subscription processing") 824 props.AddDurationProperty(pathReportActivityFrequency, 5*time.Minute, "The time interval at which the agent polls for event changes for the periodic agent status updater") 825 props.AddStringProperty(pathAPIValidationCronSchedule, "@daily", "The cron schedule at which the agent validates API Services with the dataplane") 826 props.AddDurationProperty(pathClientTimeout, 60*time.Second, "The time interval at which the http client times out making HTTP requests and processing the response", properties.WithLowerLimit(15*time.Second), properties.WithUpperLimit(120*time.Second)) 827 props.AddIntProperty(pathPageSize, 100, "The max page size the agent will use while retrieving API Server resources", properties.WithLowerLimitInt(10), properties.WithUpperLimitInt(100)) 828 props.AddStringProperty(pathAPIServiceRevisionPattern, "", "The naming pattern for APIServiceRevision Title") 829 props.AddStringProperty(pathAPIServerVersion, "v1alpha1", "Version of the API Server") 830 props.AddDurationProperty(pathJobTimeout, 5*time.Minute, "The max time a job execution can run before being considered as failed") 831 // Watch stream config 832 props.AddBoolProperty(pathGRPCEnabled, false, "Controls whether an agent uses a gRPC connection") 833 props.AddStringProperty(pathGRPCHost, "", "Host name for Amplify Central gRPC connection") 834 props.AddIntProperty(pathGRPCPort, 0, "Port for Amplify Central gRPC connection") 835 props.AddBoolProperty(pathGRPCInsecure, false, "Controls whether an agent uses a gRPC connection with TLS") 836 props.AddStringProperty(pathCacheStoragePath, "", "The directory path where agent cache will be persisted to file") 837 props.AddDurationProperty(pathCacheStorageInterval, 10*time.Second, "The interval to persist agent caches to file", properties.WithLowerLimit(10*time.Second)) 838 props.AddStringSliceProperty(pathCredentialsOAuthMethods, []string{}, "Allowed OAuth credential types") 839 840 if supportsTraceability(agentType) { 841 props.AddStringProperty(pathEnvironmentID, "", "Offline Usage Reporting Only. The Environment ID the usage is associated with on Amplify Central") 842 props.AddStringProperty(pathDeployment, "", "Amplify Central") 843 AddMetricReportingProperties(props) 844 AddUsageReportingProperties(props) 845 } else { 846 props.AddStringProperty(pathAdditionalTags, "", "Additional Tags to Add to discovered APIs when publishing to Amplify Central") 847 props.AddBoolProperty(pathAppendEnvironmentToTitle, true, "When true API titles and descriptions will be appended with environment name") 848 AddMigrationConfigProperties(props) 849 } 850 } 851 852 // ParseCentralConfig - Parses the Central Config values from the command line 853 func ParseCentralConfig(props properties.Properties, agentType AgentType) (CentralConfig, error) { 854 region := US 855 regionSet := false 856 if r, ok := nameToRegionMap[props.StringPropertyValue(pathRegion)]; ok { 857 region = r 858 regionSet = true 859 } 860 861 regSet := regionalSettingsMap[region] 862 863 // check if CENTRAL_SINGLEURL is explicitly empty 864 _, set := os.LookupEnv("CENTRAL_SINGLEURL") 865 866 var metricReporting MetricReportingConfig 867 var usageReporting UsageReportingConfig 868 if supportsTraceability(agentType) { 869 metricReporting = ParseMetricReportingConfig(props) 870 usageReporting = ParseUsageReportingConfig(props) 871 if usageReporting.IsOfflineMode() { 872 // Check if this is offline usage reporting only 873 cfg := &CentralConfiguration{ 874 AgentName: props.StringPropertyValue(pathAgentName), 875 AgentType: agentType, 876 UsageReporting: usageReporting, 877 MetricReporting: metricReporting, 878 } 879 // only need the environment ID in offline mode 880 cfg.EnvironmentID = props.StringPropertyValue(pathEnvironmentID) 881 return cfg, nil 882 } 883 } 884 885 proxyURL := props.StringPropertyValue(pathProxyURL) 886 887 cfg := &CentralConfiguration{ 888 AgentType: agentType, 889 RegionSettings: regSet, 890 Region: region, 891 TenantID: props.StringPropertyValue(pathTenantID), 892 PollInterval: props.DurationPropertyValue(pathPollInterval), 893 ReportActivityFrequency: props.DurationPropertyValue(pathReportActivityFrequency), 894 APIValidationCronSchedule: props.StringPropertyValue(pathAPIValidationCronSchedule), 895 JobExecutionTimeout: props.DurationPropertyValue(pathJobTimeout), 896 ClientTimeout: props.DurationPropertyValue(pathClientTimeout), 897 PageSize: props.IntPropertyValue(pathPageSize), 898 APIServiceRevisionPattern: props.StringPropertyValue(pathAPIServiceRevisionPattern), 899 Environment: props.StringPropertyValue(pathEnvironment), 900 TeamName: props.StringPropertyValue(pathTeam), 901 AgentName: props.StringPropertyValue(pathAgentName), 902 Auth: &AuthConfiguration{ 903 RegionSettings: regSet, 904 URL: strings.TrimRight(props.StringPropertyValue(pathAuthURL), urlCutSet), 905 Realm: props.StringPropertyValue(pathAuthRealm), 906 ClientID: props.StringPropertyValue(pathAuthClientID), 907 PrivateKey: props.StringPropertyValue(pathAuthPrivateKey), 908 PublicKey: props.StringPropertyValue(pathAuthPublicKey), 909 KeyPwd: props.StringPropertyValue(pathAuthKeyPassword), 910 Timeout: props.DurationPropertyValue(pathAuthTimeout), 911 }, 912 TLS: &TLSConfiguration{ 913 NextProtos: props.StringSlicePropertyValue(pathSSLNextProtos), 914 InsecureSkipVerify: props.BoolPropertyValue(pathSSLInsecureSkipVerify), 915 CipherSuites: NewCipherArray(props.StringSlicePropertyValue(pathSSLCipherSuites)), 916 MinVersion: TLSVersionAsValue(props.StringPropertyValue(pathSSLMinVersion)), 917 MaxVersion: TLSVersionAsValue(props.StringPropertyValue(pathSSLMaxVersion)), 918 }, 919 ProxyURL: proxyURL, 920 GRPCCfg: GRPCConfig{ 921 Enabled: props.BoolPropertyValue(pathGRPCEnabled), 922 Host: props.StringPropertyValue(pathGRPCHost), 923 Port: props.IntPropertyValue(pathGRPCPort), 924 Insecure: props.BoolPropertyValue(pathGRPCInsecure), 925 }, 926 CacheStoragePath: props.StringPropertyValue(pathCacheStoragePath), 927 CacheStorageInterval: props.DurationPropertyValue(pathCacheStorageInterval), 928 } 929 cfg.URL = strings.TrimRight(props.StringPropertyValue(pathURL), urlCutSet) 930 cfg.SingleURL = strings.TrimRight(props.StringPropertyValue(pathSingleURL), urlCutSet) 931 cfg.isSingleURLSet = set 932 cfg.isRegionSet = regionSet 933 cfg.PlatformURL = strings.TrimRight(props.StringPropertyValue(pathPlatformURL), urlCutSet) 934 cfg.APIServerVersion = props.StringPropertyValue(pathAPIServerVersion) 935 cfg.APIServiceRevisionPattern = props.StringPropertyValue(pathAPIServiceRevisionPattern) 936 cfg.CredentialConfig = newCredentialConfig() 937 if supportsTraceability(agentType) { 938 cfg.APICDeployment = props.StringPropertyValue(pathDeployment) 939 cfg.UsageReporting = usageReporting 940 cfg.MetricReporting = metricReporting 941 } else { 942 cfg.TeamName = props.StringPropertyValue(pathTeam) 943 cfg.TagsToPublish = props.StringPropertyValue(pathAdditionalTags) 944 cfg.AppendEnvironmentToTitle = props.BoolPropertyValue(pathAppendEnvironmentToTitle) 945 cfg.MigrationSettings = ParseMigrationConfig(props) 946 cfg.CredentialConfig = newCredentialConfig() 947 cfg.CredentialConfig.SetAllowedOAuthMethods(props.StringSlicePropertyValue(pathCredentialsOAuthMethods)) 948 } 949 if cfg.AgentName == "" && cfg.Environment != "" && agentType.ToShortString() != "" { 950 cfg.AgentName = cfg.Environment + "-" + agentType.ToShortString() 951 } 952 if regionSet { 953 regSet := regionalSettingsMap[region] 954 cfg.RegionSettings = regSet 955 authCfg, ok := cfg.Auth.(*AuthConfiguration) 956 if ok { 957 authCfg.RegionSettings = regSet 958 authCfg.URL = regSet.AuthURL 959 } 960 961 cfg.URL = regSet.CentralURL 962 cfg.PlatformURL = regSet.PlatformURL 963 cfg.APICDeployment = regSet.Deployment 964 } 965 966 return cfg, nil 967 } 968 969 func supportsTraceability(agentType AgentType) bool { 970 return agentType == TraceabilityAgent 971 }