woodpecker/pipeline/frontend/yaml/types/network.go
2023-08-10 11:06:00 +02:00

118 lines
3.2 KiB
Go

// Copyright 2023 Woodpecker Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"errors"
"fmt"
)
// Networks represents a list of service networks in compose file.
// It has several representation, hence this specific struct.
type Networks struct {
Networks []*Network
}
// Network represents a service network in compose file.
type Network struct {
Name string `yaml:"-"`
Aliases []string `yaml:"aliases,omitempty"`
IPv4Address string `yaml:"ipv4_address,omitempty"`
IPv6Address string `yaml:"ipv6_address,omitempty"`
}
// MarshalYAML implements the Marshaller interface.
func (n Networks) MarshalYAML() (interface{}, error) {
m := map[string]*Network{}
for _, network := range n.Networks {
m[network.Name] = network
}
return m, nil
}
// UnmarshalYAML implements the Unmarshaler interface.
func (n *Networks) UnmarshalYAML(unmarshal func(interface{}) error) error {
var sliceType []interface{}
if err := unmarshal(&sliceType); err == nil {
n.Networks = []*Network{}
for _, network := range sliceType {
name, ok := network.(string)
if !ok {
return fmt.Errorf("Cannot unmarshal '%v' to type %T into a string value", name, name)
}
n.Networks = append(n.Networks, &Network{
Name: name,
})
}
return nil
}
var mapType map[interface{}]interface{}
if err := unmarshal(&mapType); err == nil {
n.Networks = []*Network{}
for mapKey, mapValue := range mapType {
name, ok := mapKey.(string)
if !ok {
return fmt.Errorf("Cannot unmarshal '%v' to type %T into a string value", name, name)
}
network, err := handleNetwork(name, mapValue)
if err != nil {
return err
}
n.Networks = append(n.Networks, network)
}
return nil
}
return errors.New("Failed to unmarshal Networks")
}
func handleNetwork(name string, value interface{}) (*Network, error) {
if value == nil {
return &Network{
Name: name,
}, nil
}
switch v := value.(type) {
case map[string]interface{}:
network := &Network{
Name: name,
}
for mapKey, mapValue := range v {
switch mapKey {
case "aliases":
aliases, ok := mapValue.([]interface{})
if !ok {
return &Network{}, fmt.Errorf("Cannot unmarshal '%v' to type %T into a string value", aliases, aliases)
}
network.Aliases = []string{}
for _, alias := range aliases {
network.Aliases = append(network.Aliases, alias.(string))
}
case "ipv4_address":
network.IPv4Address = mapValue.(string)
case "ipv6_address":
network.IPv6Address = mapValue.(string)
default:
// Ignorer unknown keys ?
continue
}
}
return network, nil
default:
return &Network{}, fmt.Errorf("Failed to unmarshal Network: %#v", value)
}
}