github.com/polarismesh/polaris@v1.17.8/plugin/cmdb/memory/memory.go (about)

     1  /**
     2   * Tencent is pleased to support the open source community by making Polaris available.
     3   *
     4   * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
     5   *
     6   * Licensed under the BSD 3-Clause License (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   * https://opensource.org/licenses/BSD-3-Clause
    11   *
    12   * Unless required by applicable law or agreed to in writing, software distributed
    13   * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    14   * CONDITIONS OF ANY KIND, either express or implied. See the License for the
    15   * specific language governing permissions and limitations under the License.
    16   */
    17  
    18  package memory
    19  
    20  import (
    21  	"context"
    22  	"encoding/json"
    23  	"sync/atomic"
    24  	"time"
    25  
    26  	"go.uber.org/zap"
    27  
    28  	commonlog "github.com/polarismesh/polaris/common/log"
    29  	"github.com/polarismesh/polaris/common/model"
    30  	"github.com/polarismesh/polaris/plugin"
    31  )
    32  
    33  const (
    34  	// PluginName plugin name
    35  	PluginName = "memory"
    36  )
    37  
    38  var (
    39  	log = commonlog.RegisterScope("cmdb", "", 0)
    40  )
    41  
    42  // init 自注册到插件列表
    43  func init() {
    44  	plugin.RegisterPlugin(PluginName, &Memory{})
    45  }
    46  
    47  // Memory 定义MemoryCMDB类
    48  type Memory struct {
    49  	fetcher Fetcher
    50  	cancel  context.CancelFunc
    51  	IPs     atomic.Value
    52  }
    53  
    54  // Name 返回插件名
    55  func (m *Memory) Name() string {
    56  	return PluginName
    57  }
    58  
    59  // Initialize 初始化函数
    60  func (m *Memory) Initialize(c *plugin.ConfigEntry) error {
    61  	url, _ := c.Option["url"].(string)
    62  	token, _ := c.Option["token"].(string)
    63  	interval, _ := c.Option["interval"].(string)
    64  
    65  	tick, err := time.ParseDuration(interval)
    66  	if err != nil {
    67  		tick = 5 * time.Minute
    68  	}
    69  
    70  	m.fetcher = &fetcher{
    71  		url:   url,
    72  		token: token,
    73  	}
    74  	ctx, cancel := context.WithCancel(context.Background())
    75  	m.cancel = cancel
    76  
    77  	go m.doFetch(ctx, tick)
    78  
    79  	return nil
    80  }
    81  
    82  // GetLocation 实现CMDB插件接口
    83  func (m *Memory) GetLocation(host string) (*model.Location, error) {
    84  	val := m.IPs.Load()
    85  	if val == nil {
    86  		return nil, nil
    87  	}
    88  	ips := val.(*IPs)
    89  
    90  	var (
    91  		target IP
    92  		find   bool
    93  	)
    94  
    95  	entry, ok := ips.Hosts[host]
    96  	if ok {
    97  		find = true
    98  		target = entry
    99  	} else {
   100  		for i := range ips.Mask {
   101  			if ips.Mask[i].Match(host) {
   102  				target = ips.Mask[i]
   103  				find = true
   104  				break
   105  			}
   106  		}
   107  		if !find && ips.Backoff != nil {
   108  			find = true
   109  			target = *ips.Backoff
   110  		}
   111  	}
   112  
   113  	if !find {
   114  		return nil, nil
   115  	}
   116  
   117  	return target.loc, nil
   118  }
   119  
   120  func (m *Memory) doFetch(ctx context.Context, interval time.Duration) {
   121  	work := func() {
   122  		ret, ips, err := m.fetcher.GetIPs()
   123  		if err != nil {
   124  			log.Error("[CMDB][Memory] fetch data from remote fail", zap.Error(err))
   125  			return
   126  		}
   127  
   128  		data, err := json.Marshal(ret)
   129  		if err != nil {
   130  			log.Error("[CMDB][Memory] marshal receive cmdb data", zap.Error(err))
   131  		} else {
   132  			log.Infof("[CMDB][Memory] receive cmdb data \n%s\n", string(data))
   133  		}
   134  
   135  		m.IPs.Store(&ips)
   136  	}
   137  
   138  	work()
   139  
   140  	ticker := time.NewTicker(interval)
   141  	for {
   142  		select {
   143  		case <-ticker.C:
   144  			work()
   145  		case <-ctx.Done():
   146  			return
   147  		}
   148  	}
   149  }
   150  
   151  // Destroy 销毁函数
   152  func (m *Memory) Destroy() error {
   153  	if m.cancel != nil {
   154  		m.cancel()
   155  	}
   156  	return nil
   157  }
   158  
   159  // Range 实现CMDB插件接口
   160  func (m *Memory) Range(handler func(host string, location *model.Location) (bool, error)) error {
   161  	val := m.IPs.Load()
   162  	if val == nil {
   163  		return nil
   164  	}
   165  	ips := val.(*IPs)
   166  
   167  	for i := range ips.Hosts {
   168  		if _, err := handler(ips.Hosts[i].IP, ips.Hosts[i].loc); err != nil {
   169  			return err
   170  		}
   171  	}
   172  
   173  	return nil
   174  }
   175  
   176  // Size 实现CMDB插件接口
   177  func (m *Memory) Size() int32 {
   178  	val := m.IPs.Load()
   179  	if val == nil {
   180  		return 0
   181  	}
   182  	ips := val.(*IPs)
   183  	return int32(len(ips.Hosts))
   184  }