func newDiscoveryTool()

in plugins/inputs/aliyuncms/discovery.go [90:278]


func newDiscoveryTool(regions []string, project string, lg telegraf.Logger, credential auth.Credential, rateLimit int, discoveryInterval time.Duration) (*discoveryTool, error) {
	var (
		dscReq                = map[string]discoveryRequest{}
		cli                   = map[string]aliyunSdkClient{}
		parseRootKey          = regexp.MustCompile(`Describe(.*)`)
		responseRootKey       string
		responseObjectIDKey   string
		err                   error
		noDiscoverySupportErr = errors.Errorf("no discovery support for project %q", project)
	)

	if len(regions) == 0 {
		regions = aliyunRegionList
		lg.Infof("'regions' is not provided! Discovery data will be queried across %d regions:\n%s",
			len(aliyunRegionList), strings.Join(aliyunRegionList, ","))
	}

	if rateLimit == 0 { //Can be a rounding case
		rateLimit = 1
	}

	for _, region := range regions {
		switch project {
		case "acs_ecs_dashboard":
			dscReq[region] = ecs.CreateDescribeInstancesRequest()
			responseObjectIDKey = "InstanceId"
		case "acs_rds_dashboard":
			dscReq[region] = rds.CreateDescribeDBInstancesRequest()
			responseObjectIDKey = "DBInstanceId"
		case "acs_slb_dashboard":
			dscReq[region] = slb.CreateDescribeLoadBalancersRequest()
			responseObjectIDKey = "LoadBalancerId"
		case "acs_memcache":
			return nil, noDiscoverySupportErr
		case "acs_ocs":
			return nil, noDiscoverySupportErr
		case "acs_oss":
			//oss is really complicated
			//it is on it's own format
			return nil, noDiscoverySupportErr

			//As a possible solution we can
			//mimic to request format supported by oss

			//req := DescribeLOSSRequest{
			//	RpcRequest: &requests.RpcRequest{},
			//}
			//req.InitWithApiInfo("oss", "2014-08-15", "DescribeDBInstances", "oss", "openAPI")
		case "acs_vpc_eip":
			dscReq[region] = vpc.CreateDescribeEipAddressesRequest()
			responseObjectIDKey = "AllocationId"
		case "acs_kvstore":
			return nil, noDiscoverySupportErr
		case "acs_mns_new":
			return nil, noDiscoverySupportErr
		case "acs_cdn":
			//API replies are in its own format.
			return nil, noDiscoverySupportErr
		case "acs_polardb":
			return nil, noDiscoverySupportErr
		case "acs_gdb":
			return nil, noDiscoverySupportErr
		case "acs_ads":
			return nil, noDiscoverySupportErr
		case "acs_mongodb":
			return nil, noDiscoverySupportErr
		case "acs_express_connect":
			return nil, noDiscoverySupportErr
		case "acs_fc":
			return nil, noDiscoverySupportErr
		case "acs_nat_gateway":
			return nil, noDiscoverySupportErr
		case "acs_sls_dashboard":
			return nil, noDiscoverySupportErr
		case "acs_containerservice_dashboard":
			return nil, noDiscoverySupportErr
		case "acs_vpn":
			return nil, noDiscoverySupportErr
		case "acs_bandwidth_package":
			return nil, noDiscoverySupportErr
		case "acs_cen":
			return nil, noDiscoverySupportErr
		case "acs_ens":
			return nil, noDiscoverySupportErr
		case "acs_opensearch":
			return nil, noDiscoverySupportErr
		case "acs_scdn":
			return nil, noDiscoverySupportErr
		case "acs_drds":
			return nil, noDiscoverySupportErr
		case "acs_iot":
			return nil, noDiscoverySupportErr
		case "acs_directmail":
			return nil, noDiscoverySupportErr
		case "acs_elasticsearch":
			return nil, noDiscoverySupportErr
		case "acs_ess_dashboard":
			return nil, noDiscoverySupportErr
		case "acs_streamcompute":
			return nil, noDiscoverySupportErr
		case "acs_global_acceleration":
			return nil, noDiscoverySupportErr
		case "acs_hitsdb":
			return nil, noDiscoverySupportErr
		case "acs_kafka":
			return nil, noDiscoverySupportErr
		case "acs_openad":
			return nil, noDiscoverySupportErr
		case "acs_pcdn":
			return nil, noDiscoverySupportErr
		case "acs_dcdn":
			return nil, noDiscoverySupportErr
		case "acs_petadata":
			return nil, noDiscoverySupportErr
		case "acs_videolive":
			return nil, noDiscoverySupportErr
		case "acs_hybriddb":
			return nil, noDiscoverySupportErr
		case "acs_adb":
			return nil, noDiscoverySupportErr
		case "acs_mps":
			return nil, noDiscoverySupportErr
		case "acs_maxcompute_prepay":
			return nil, noDiscoverySupportErr
		case "acs_hdfs":
			return nil, noDiscoverySupportErr
		case "acs_ddh":
			return nil, noDiscoverySupportErr
		case "acs_hbr":
			return nil, noDiscoverySupportErr
		case "acs_hdr":
			return nil, noDiscoverySupportErr
		case "acs_cds":
			return nil, noDiscoverySupportErr
		default:
			return nil, errors.Errorf("project %q is not recognized by discovery...", project)
		}

		cli[region], err = sdk.NewClientWithOptions(region, sdk.NewConfig(), credential)
		if err != nil {
			return nil, err
		}
	}

	if len(dscReq) == 0 || len(cli) == 0 {
		return nil, errors.Errorf("Can't build discovery request for project: %q,\nregions: %v", project, regions)
	}

	//Getting response root key (if not set already). This is to be able to parse discovery responses
	//As they differ per object type
	//Discovery requests are of the same type per every region, so pick the first one
	rpcReq, err := getRPCReqFromDiscoveryRequest(dscReq[regions[0]])
	//This means that the discovery request is not of proper type/kind
	if err != nil {
		return nil, errors.Errorf("Can't parse rpc request object from  discovery request %v", dscReq[regions[0]])
	}

	/*
		The action name is of the following format Describe<Project related title for managed instances>,
		For example: DescribeLoadBalancers -> for SLB project, or DescribeInstances for ECS project
		We will use it to construct root key name in the discovery API response.
		It follows the following logic: for 'DescribeLoadBalancers' action in discovery request we get the response
		in json of the following structure:
		{
			 ...
			 "LoadBalancers": {
				 "LoadBalancer": [ here comes objects, one per every instance]
			}
		}
		As we can see, the root key is a part of action name, except first word (part) 'Describe'
	*/
	result := parseRootKey.FindStringSubmatch(rpcReq.GetActionName())
	if result == nil || len(result) != 2 {
		return nil, errors.Errorf("Can't parse the discovery response root key from request action name %q", rpcReq.GetActionName())
	}
	responseRootKey = result[1]

	return &discoveryTool{
		req:                dscReq,
		cli:                cli,
		respRootKey:        responseRootKey,
		respObjectIDKey:    responseObjectIDKey,
		rateLimit:          rateLimit,
		interval:           discoveryInterval,
		reqDefaultPageSize: 20,
		dataChan:           make(chan map[string]interface{}, 1),
		lg:                 lg,
	}, nil
}