// ToTemplateArgs is converter Menu to TemplateArgs
ToTemplateArgs is converter Menu to TemplateArgs
// ToTemplateArgs is converter Menu to TemplateArgs
func ToTemplateArgs(menu *Menu) (*TemplateArgs, error) {
	var templateArgs TemplateArgs
	setNetworkArgs(&templateArgs, menu)
	templateArgs.Images = menu.Images
	definedImages := map[string]bool{}
	for _, image := range menu.Images {
		definedImages[image.Name] = true
	}
	for _, node := range menu.Nodes {
		switch node.Type {
		case CSNode:
			templateArgs.CS.Memory = node.Memory
			templateArgs.CS.CPU = node.CPU
			templateArgs.CS.Image = node.Image
			templateArgs.CS.Data = node.Data
			templateArgs.CS.UEFI = node.UEFI
			templateArgs.CS.CloudInitTemplate = node.CloudInitTemplate
		case SSNode:
			templateArgs.SS.Memory = node.Memory
			templateArgs.SS.CPU = node.CPU
			templateArgs.SS.Image = node.Image
			templateArgs.SS.Data = node.Data
			templateArgs.SS.UEFI = node.UEFI
			templateArgs.SS.CloudInitTemplate = node.CloudInitTemplate
		case BootNode:
			templateArgs.Boot.Memory = node.Memory
			templateArgs.Boot.CPU = node.CPU
			templateArgs.Boot.Image = node.Image
			templateArgs.Boot.Data = node.Data
			templateArgs.Boot.UEFI = node.UEFI
			templateArgs.Boot.CloudInitTemplate = node.CloudInitTemplate
		default:
			return nil, errors.New("invalid node type")
		}
		requiredImages := node.Data
		if len(node.Image) > 0 {
			requiredImages = append(requiredImages, node.Image)
		}
		for _, img := range requiredImages {
			if !definedImages[img] {
				return nil, errors.New("no such Image resource: " + node.Image)
			}
		}
	}
	templateArgs.ClusterID = menu.Inventory.ClusterID
	numRack := len(menu.Inventory.Rack)
	spineToRackBases := make([][]net.IP, menu.Inventory.Spine)
	spineTorInt := netutil.IP4ToInt(menu.Network.SpineTor)
	for spineIdx := 0; spineIdx < menu.Inventory.Spine; spineIdx++ {
		spineToRackBases[spineIdx] = make([]net.IP, numRack)
		for rackIdx := range menu.Inventory.Rack {
			offset := uint32((spineIdx*numRack + rackIdx) * torPerRack * 2)
			spineToRackBases[spineIdx][rackIdx] = netutil.IntToIP4(spineTorInt + offset)
		}
	}
	templateArgs.Racks = make([]Rack, numRack)
	for rackIdx, rackMenu := range menu.Inventory.Rack {
		rack := &templateArgs.Racks[rackIdx]
		rack.Name = fmt.Sprintf("rack%d", rackIdx)
		rack.Index = rackIdx
		rack.ShortName = fmt.Sprintf("r%d", rackIdx)
		rack.ASN = menu.Network.ASNBase + rackIdx
		rack.node0Network = makeNodeNetwork(menu.Network.NodeBase, menu.Network.NodeRangeSize, menu.Network.NodeRangeMask, rackIdx*3+0)
		rack.node1Network = makeNodeNetwork(menu.Network.NodeBase, menu.Network.NodeRangeSize, menu.Network.NodeRangeMask, rackIdx*3+1)
		rack.node2Network = makeNodeNetwork(menu.Network.NodeBase, menu.Network.NodeRangeSize, menu.Network.NodeRangeMask, rackIdx*3+2)
		constructToRAddresses(rack, rackIdx, menu, spineToRackBases)
		buildBootNode(rack, menu)
		rack.NodeNetworkPrefixSize = menu.Network.NodeRangeMask
		for csIdx := 0; csIdx < rackMenu.CS; csIdx++ {
			node := buildNode("cs", csIdx, offsetNodenetServers, rack)
			rack.CSList = append(rack.CSList, node)
		}
		for ssIdx := 0; ssIdx < rackMenu.SS; ssIdx++ {
			node := buildNode("ss", ssIdx, offsetNodenetServers+rackMenu.CS, rack)
			rack.SSList = append(rack.SSList, node)
		}
	}
	templateArgs.Spines = make([]Spine, menu.Inventory.Spine)
	for spineIdx := 0; spineIdx < menu.Inventory.Spine; spineIdx++ {
		spine := &templateArgs.Spines[spineIdx]
		spine.Name = fmt.Sprintf("spine%d", spineIdx+1)
		spine.ShortName = fmt.Sprintf("s%d", spineIdx+1)
		spine.CoreAddress = addToIPNet(menu.Network.CoreSpine, (2*spineIdx)+1)
		spine.ToRAddresses = make([]*net.IPNet, torPerRack*numRack)
		for rackIdx := range menu.Inventory.Rack {
			spine.ToRAddresses[rackIdx*torPerRack] = addToIP(spineToRackBases[spineIdx][rackIdx], 0, 31)
			spine.ToRAddresses[rackIdx*torPerRack+1] = addToIP(spineToRackBases[spineIdx][rackIdx], 2, 31)
		}
	}
	setCore(&templateArgs, menu)
	return &templateArgs, nil
}
func ToTemplateArgs ( menu * Menu ) ( * TemplateArgs , error ) { var templateArgs TemplateArgs setNetworkArgs ( & templateArgs , menu ) templateArgs . Images = menu . Images definedImages := map [ string ] bool { } for _ , image := range menu . Images { definedImages [ image . Name ] = true } for _ , node := range menu . Nodes { switch node . Type { case CSNode : templateArgs . CS . Memory = node . Memory templateArgs . CS . CPU = node . CPU templateArgs . CS . Image = node . Image templateArgs . CS . Data = node . Data templateArgs . CS . UEFI = node . UEFI templateArgs . CS . CloudInitTemplate = node . CloudInitTemplate case SSNode : templateArgs . SS . Memory = node . Memory templateArgs . SS . CPU = node . CPU templateArgs . SS . Image = node . Image templateArgs . SS . Data = node . Data templateArgs . SS . UEFI = node . UEFI templateArgs . SS . CloudInitTemplate = node . CloudInitTemplate case BootNode : templateArgs . Boot . Memory = node . Memory templateArgs . Boot . CPU = node . CPU templateArgs . Boot . Image = node . Image templateArgs . Boot . Data = node . Data templateArgs . Boot . UEFI = node . UEFI templateArgs . Boot . CloudInitTemplate = node . CloudInitTemplate default : return nil , errors . New ( " " ) } requiredImages := node . Data if len ( node . Image ) > 0 { requiredImages = append ( requiredImages , node . Image ) } for _ , img := range requiredImages { if ! definedImages [ img ] { return nil , errors . New ( " " + node . Image ) } } } templateArgs . ClusterID = menu . Inventory . ClusterID numRack := len ( menu . Inventory . Rack ) spineToRackBases := make ( [ ] [ ] net . IP , menu . Inventory . Spine ) spineTorInt := netutil . IP4ToInt ( menu . Network . SpineTor ) for spineIdx := 0 ; spineIdx < menu . Inventory . Spine ; spineIdx ++ { spineToRackBases [ spineIdx ] = make ( [ ] net . IP , numRack ) for rackIdx := range menu . Inventory . Rack { offset := uint32 ( ( spineIdx * numRack + rackIdx ) * torPerRack * 2 ) spineToRackBases [ spineIdx ] [ rackIdx ] = netutil . IntToIP4 ( spineTorInt + offset ) } } templateArgs . Racks = make ( [ ] Rack , numRack ) for rackIdx , rackMenu := range menu . Inventory . Rack { rack := & templateArgs . Racks [ rackIdx ] rack . Name = fmt . Sprintf ( " " , rackIdx ) rack . Index = rackIdx rack . ShortName = fmt . Sprintf ( " " , rackIdx ) rack . ASN = menu . Network . ASNBase + rackIdx rack . node0Network = makeNodeNetwork ( menu . Network . NodeBase , menu . Network . NodeRangeSize , menu . Network . NodeRangeMask , rackIdx * 3 + 0 ) rack . node1Network = makeNodeNetwork ( menu . Network . NodeBase , menu . Network . NodeRangeSize , menu . Network . NodeRangeMask , rackIdx * 3 + 1 ) rack . node2Network = makeNodeNetwork ( menu . Network . NodeBase , menu . Network . NodeRangeSize , menu . Network . NodeRangeMask , rackIdx * 3 + 2 ) constructToRAddresses ( rack , rackIdx , menu , spineToRackBases ) buildBootNode ( rack , menu ) rack . NodeNetworkPrefixSize = menu . Network . NodeRangeMask for csIdx := 0 ; csIdx < rackMenu . CS ; csIdx ++ { node := buildNode ( " " , csIdx , offsetNodenetServers , rack ) rack . CSList = append ( rack . CSList , node ) } for ssIdx := 0 ; ssIdx < rackMenu . SS ; ssIdx ++ { node := buildNode ( " " , ssIdx , offsetNodenetServers + rackMenu . CS , rack ) rack . SSList = append ( rack . SSList , node ) } } templateArgs . Spines = make ( [ ] Spine , menu . Inventory . Spine ) for spineIdx := 0 ; spineIdx < menu . Inventory . Spine ; spineIdx ++ { spine := & templateArgs . Spines [ spineIdx ] spine . Name = fmt . Sprintf ( " " , spineIdx + 1 ) spine . ShortName = fmt . Sprintf ( " " , spineIdx + 1 ) spine . CoreAddress = addToIPNet ( menu . Network . CoreSpine , ( 2 * spineIdx ) + 1 ) spine . ToRAddresses = make ( [ ] * net . IPNet , torPerRack * numRack ) for rackIdx := range menu . Inventory . Rack { spine . ToRAddresses [ rackIdx * torPerRack ] = addToIP ( spineToRackBases [ spineIdx ] [ rackIdx ] , 0 , 31 ) spine . ToRAddresses [ rackIdx * torPerRack + 1 ] = addToIP ( spineToRackBases [ spineIdx ] [ rackIdx ] , 2 , 31 ) } } setCore ( & templateArgs , menu ) return & templateArgs , nil }
ToTemplateArgs is converter Menu to TemplateArgs
ToTemplateArgs is converter Menu to TemplateArgs
// {internet} + {tor per rack} * {rack}