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