interface.go raw

   1  // Copyright 2022-2025 The sacloud/iaas-api-go Authors
   2  //
   3  // Licensed under the Apache License, Version 2.0 (the "License");
   4  // you may not use this file except in compliance with the License.
   5  // You may obtain a copy of the License at
   6  //
   7  //      http://www.apache.org/licenses/LICENSE-2.0
   8  //
   9  // Unless required by applicable law or agreed to in writing, software
  10  // distributed under the License is distributed on an "AS IS" BASIS,
  11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12  // See the License for the specific language governing permissions and
  13  // limitations under the License.
  14  
  15  package naked
  16  
  17  import (
  18  	"encoding/json"
  19  
  20  	"github.com/sacloud/iaas-api-go/types"
  21  )
  22  
  23  // Interface サーバなどに接続されているNICの情報
  24  type Interface struct {
  25  	ID            types.ID          `json:",omitempty" yaml:"id,omitempty" structs:",omitempty"`
  26  	MACAddress    string            `json:",omitempty" yaml:"mac_address,omitempty" structs:",omitempty"`
  27  	IPAddress     string            `json:",omitempty" yaml:"ip_address,omitempty" structs:",omitempty"`
  28  	UserIPAddress string            `json:",omitempty" yaml:"user_ip_address,omitempty" structs:",omitempty"`
  29  	HostName      string            `json:",omitempty" yaml:"host_name,omitempty" structs:",omitempty"`
  30  	Switch        *Switch           `json:",omitempty" yaml:"switch,omitempty" structs:",omitempty"`
  31  	PacketFilter  *PacketFilterInfo `json:",omitempty" yaml:"packet_filter,omitempty" structs:",omitempty"`
  32  	Server        *Server           `json:",omitempty" yaml:"server,omitempty" structs:",omitempty"`
  33  
  34  	// Index 仮想フィールド、VPCルータなどでInterfaces(実体は[]*Interface)を扱う場合にUnmarshalJSONの中で設定される
  35  	//
  36  	// Findした際のAPIからの応答にも同名のフィールドが含まれるが無関係。
  37  	Index int
  38  
  39  	// UpstreamType 上流ネットワーク種別 UnmarshalJSONの中で算出される
  40  	UpstreamType types.EUpstreamNetworkType
  41  }
  42  
  43  // Interfaces Interface配列
  44  //
  45  // 配列中にnullが返ってくる(VPCルータなど)への対応のためのtype
  46  type Interfaces []*Interface
  47  
  48  // UnmarshalJSON 配列中にnullが返ってくる(VPCルータなど)への対応
  49  func (i *Interfaces) UnmarshalJSON(b []byte) error {
  50  	type alias Interfaces
  51  	var a alias
  52  	if err := json.Unmarshal(b, &a); err != nil {
  53  		return err
  54  	}
  55  
  56  	var dest []*Interface
  57  	for i, v := range a {
  58  		if v != nil {
  59  			if v.Index == 0 {
  60  				v.Index = i
  61  			}
  62  			dest = append(dest, v)
  63  		}
  64  	}
  65  
  66  	*i = Interfaces(dest)
  67  	return nil
  68  }
  69  
  70  // MarshalJSON 配列中にnullが入る場合(VPCルータなど)への対応
  71  func (i Interfaces) MarshalJSON() ([]byte, error) {
  72  	max := 0
  73  	for _, iface := range i {
  74  		if max < iface.Index {
  75  			max = iface.Index
  76  		}
  77  	}
  78  
  79  	var dest = make([]*Interface, max+1)
  80  	for _, iface := range i {
  81  		dest[iface.Index] = iface
  82  	}
  83  
  84  	return json.Marshal(dest)
  85  }
  86  
  87  // MarshalJSON Indexフィールドを出力しないための実装
  88  func (i *Interface) MarshalJSON() ([]byte, error) {
  89  	type alias struct {
  90  		ID            types.ID          `json:",omitempty" yaml:"id,omitempty" structs:",omitempty"`
  91  		MACAddress    string            `json:",omitempty" yaml:"mac_address,omitempty" structs:",omitempty"`
  92  		IPAddress     string            `json:",omitempty" yaml:"ip_address,omitempty" structs:",omitempty"`
  93  		UserIPAddress string            `json:",omitempty" yaml:"user_ip_address,omitempty" structs:",omitempty"`
  94  		HostName      string            `json:",omitempty" yaml:"host_name,omitempty" structs:",omitempty"`
  95  		Switch        *Switch           `json:",omitempty" yaml:"switch,omitempty" structs:",omitempty"`
  96  		PacketFilter  *PacketFilterInfo `json:",omitempty" yaml:"packet_filter,omitempty" structs:",omitempty"`
  97  		Server        *Server           `json:",omitempty" yaml:"server,omitempty" structs:",omitempty"`
  98  	}
  99  
 100  	tmp := alias{
 101  		ID:            i.ID,
 102  		MACAddress:    i.MACAddress,
 103  		IPAddress:     i.IPAddress,
 104  		UserIPAddress: i.UserIPAddress,
 105  		HostName:      i.HostName,
 106  		Switch:        i.Switch,
 107  		PacketFilter:  i.PacketFilter,
 108  		Server:        i.Server,
 109  	}
 110  	return json.Marshal(tmp)
 111  }
 112  
 113  // UnmarshalJSON 仮想フィールド UpstreamType を表現するための実装
 114  func (i *Interface) UnmarshalJSON(b []byte) error {
 115  	type alias Interface
 116  	var tmp alias
 117  	if err := json.Unmarshal(b, &tmp); err != nil {
 118  		return err
 119  	}
 120  
 121  	// calculate UpstreamType
 122  	var upstreamType types.EUpstreamNetworkType
 123  	sw := tmp.Switch
 124  	switch {
 125  	case sw == nil:
 126  		upstreamType = types.UpstreamNetworkTypes.None
 127  	case sw.Subnet == nil:
 128  		upstreamType = types.UpstreamNetworkTypes.Switch
 129  	case sw.Scope == types.Scopes.Shared:
 130  		upstreamType = types.UpstreamNetworkTypes.Shared
 131  	default:
 132  		upstreamType = types.UpstreamNetworkTypes.Router
 133  	}
 134  	tmp.UpstreamType = upstreamType
 135  
 136  	*i = Interface(tmp)
 137  	return nil
 138  }
 139