func (n *Namespace) IsClientIPAllowed(clientIP net.IP) bool {
	if len(n.allowips) == 0 {
		return true
	}
	for _, ip := range n.allowips {
		if ip.Match(clientIP) {
			return true
		}
	}
	return false
}
IsClientIPAllowed check ip
package server
import (
	"errors"
	"fmt"
	"net"
	"strconv"
	"strings"
	"time"
	"github.com/nooncall/shazam/backend"
	"github.com/nooncall/shazam/log"
	"github.com/nooncall/shazam/models"
	"github.com/nooncall/shazam/mysql"
	"github.com/nooncall/shazam/proxy/plan"
	"github.com/nooncall/shazam/proxy/router"
	"github.com/nooncall/shazam/proxy/sequence"
	"github.com/nooncall/shazam/util"
	"github.com/nooncall/shazam/util/cache"
)
const (
	namespaceDelayClose = 60
)
const (
	defaultSQLCacheCapacity  = 64
	defaultPlanCacheCapacity = 128
	defaultSlowSQLTime = 1000  
)
type UserProperty struct {
	RWFlag        int
	RWSplit       int
	OtherProperty int
}
type Namespace struct {
	name               string
	allowedDBs         map[string]bool
	defaultPhyDBs      map[string]string  
	sqls               map[string]string  
	slowSQLTime        int64              
	allowips           []util.IPInfo
	router             *router.Router
	sequences          *sequence.SequenceManager
	slices             map[string]*backend.Slice  
	userProperties     map[string]*UserProperty   
	defaultCharset     string
	defaultCollationID mysql.CollationID
	slowSQLCache         *cache.LRUCache
	errorSQLCache        *cache.LRUCache
	backendSlowSQLCache  *cache.LRUCache
	backendErrorSQLCache *cache.LRUCache
	planCache            *cache.LRUCache
}
func (n *Namespace) DumpToJSON() []byte {
	return models.JSONEncode(n)
}
func NewNamespace(namespaceConfig *models.Namespace) (*Namespace, error) {
	var err error
	namespace := &Namespace{
		name:                 namespaceConfig.Name,
		sqls:                 make(map[string]string, 16),
		userProperties:       make(map[string]*UserProperty, 2),
		slowSQLCache:         cache.NewLRUCache(defaultSQLCacheCapacity),
		errorSQLCache:        cache.NewLRUCache(defaultSQLCacheCapacity),
		backendSlowSQLCache:  cache.NewLRUCache(defaultSQLCacheCapacity),
		backendErrorSQLCache: cache.NewLRUCache(defaultSQLCacheCapacity),
		planCache:            cache.NewLRUCache(defaultPlanCacheCapacity),
	}
	defer func() {
		if err != nil {
			namespace.Close(false)
		}
	}()
	namespace.sqls = parseBlackSqls(namespaceConfig.BlackSQL)
	namespace.slowSQLTime, err = parseSlowSQLTime(namespaceConfig.SlowSQLTime)
	if err != nil {
		return nil, fmt.Errorf("parse slowSQLTime error: %v", err)
	}
	allowDBs := make(map[string]bool, len(namespaceConfig.AllowedDBS))
	for db, allowed := range namespaceConfig.AllowedDBS {
		allowDBs[strings.TrimSpace(db)] = allowed
	}
	namespace.allowedDBs = allowDBs
	defaultPhyDBs := make(map[string]string, len(namespaceConfig.DefaultPhyDBS))
	for db, phyDB := range namespaceConfig.DefaultPhyDBS {
		defaultPhyDBs[strings.TrimSpace(db)] = strings.TrimSpace(phyDB)
	}
	namespace.defaultPhyDBs, err = parseDefaultPhyDB(defaultPhyDBs, allowDBs)
	if err != nil {
		return nil, fmt.Errorf("parse defaultPhyDBs error: %v", err)
	}
	allowips, err := parseAllowIps(namespaceConfig.AllowedIP)
	if err != nil {
		return nil, fmt.Errorf("parse allowips error: %v", err)
	}
	namespace.allowips = allowips
	namespace.defaultCharset, namespace.defaultCollationID, err = parseCharset(namespaceConfig.DefaultCharset, namespaceConfig.DefaultCollation)
	if err != nil {
		return nil, fmt.Errorf("parse charset error: %v", err)
	}
	for _, user := range namespaceConfig.Users {
		up := &UserProperty{RWFlag: user.RWFlag, RWSplit: user.RWSplit, OtherProperty: user.OtherProperty}
		namespace.userProperties[user.UserName] = up
	}
	namespace.slices, err = parseSlices(namespaceConfig.Slices, namespace.defaultCharset, namespace.defaultCollationID)
	if err != nil {
		return nil, fmt.Errorf("init slices of namespace: %s failed, err: %v", namespaceConfig.Name, err)
	}
	namespace.router, err = router.NewRouter(namespaceConfig)
	if err != nil {
		return nil, fmt.Errorf("init router of namespace: %s failed, err: %v", namespace.name, err)
	}
	sequences := sequence.NewSequenceManager()
	for _, v := range namespaceConfig.GlobalSequences {
		globalSequenceSlice, ok := namespace.slices[v.SliceName]
		if !ok {
			return nil, fmt.Errorf("init global sequence error: slice not found, sequence: %v", v)
		}
		seqName := strings.ToUpper(v.DB) + "." + strings.ToUpper(v.Table)
		seq := sequence.NewMySQLSequence(globalSequenceSlice, seqName, v.PKName)
		sequences.SetSequence(v.DB, v.Table, seq)
	}
	namespace.sequences = sequences
	return namespace, nil
}
func (n *Namespace) GetName() string {
	return n.name
}
func (n *Namespace) GetSlice(name string) *backend.Slice {
	return n.slices[name]
}
func (n *Namespace) GetRouter() *router.Router {
	return n.router
}
func (n *Namespace) GetSequences() *sequence.SequenceManager {
	return n.sequences
}