<commit_before>package ginstance

import (
	"reflect"
	"sort"

	bosherr "github.com/cloudfoundry/bosh-agent/errors"

	"github.com/frodenas/bosh-google-cpi/api"
	"github.com/frodenas/bosh-google-cpi/google/util"
	"google.golang.org/api/compute/v1"
)

func (i GoogleInstanceService) ConfigureNetworks(id string, instanceNetworks GoogleInstanceNetworks) error {
	instance, found, err := i.Find(id, "")
	if err != nil {
		return err
	}
	if !found {
		return bosherr.Errorf("Google Instance '%s' not found", id)
	}

	// TODO: Configure VIP network

	if err := i.addToTargetPool(instance, instanceNetworks); err != nil {
		return err
	}

	return nil
}

func (i GoogleInstanceService) addToTargetPool(instance *compute.Instance, instanceNetworks GoogleInstanceNetworks) error {
	targetPoolName := instanceNetworks.TargetPool()

	if targetPoolName != "" {
		err := instanceNetworks.targetPoolService.AddInstance(targetPoolName, instance.SelfLink)
		if err != nil {
			return err
		}
	}

	return nil
}

func (i GoogleInstanceService) UpdateNetworks(id string, instanceNetworks GoogleInstanceNetworks) error {
	instance, found, err := i.Find(id, "")
	if err != nil {
		return err
	}
	if !found {
		return bosherr.Errorf("Google Instance '%s' not found", id)
	}

	if err = i.updateNetwork(instance, instanceNetworks); err != nil {
		return err
	}

	if err = i.updateIpForwarding(instance, instanceNetworks); err != nil {
		return err
	}

	if err = i.updateEphemeralExternalIp(instance, instanceNetworks); err != nil {
		return err
	}

	if err = i.updateTags(instance, instanceNetworks); err != nil {
		return err
	}

	if err := i.updateTargetPool(instance, instanceNetworks); err != nil {
		return err
	}

	return nil
}

func (i GoogleInstanceService) updateNetwork(instance *compute.Instance, instanceNetworks GoogleInstanceNetworks) error {
	// If the network has changed we need to recreate the VM
	dynamicNetwork := instanceNetworks.DynamicNetwork()
	if gutil.ResourceSplitter(instance.NetworkInterfaces[0].Network) != dynamicNetwork.NetworkName {
		i.logger.Debug(googleInstanceServiceLogTag, "Changing network for Google Instance '%s' not supported", instance.Name)
		return api.NotSupportedError{}
	}

	return nil
}

func (i GoogleInstanceService) updateIpForwarding(instance *compute.Instance, instanceNetworks GoogleInstanceNetworks) error {
	// If IP Forwarding has changed we need to recreate the VM
	if instance.CanIpForward != instanceNetworks.CanIpForward() {
		i.logger.Debug(googleInstanceServiceLogTag, "Changing IP Forwarding for Google Instance '%s' not supported", instance.Name)
		return api.NotSupportedError{}
	}

	return nil
}

func (i GoogleInstanceService) updateEphemeralExternalIp(instance *compute.Instance, instanceNetworks GoogleInstanceNetworks) error {
	var instanceExternalIp string

	if len(instance.NetworkInterfaces[0].AccessConfigs) > 0 {
		instanceExternalIp = instance.NetworkInterfaces[0].AccessConfigs[0].NatIP
	}

	if instanceNetworks.EphemeralExternalIP() {
		if instanceExternalIp == "" {
			networkInterface := instance.NetworkInterfaces[0].Name
			accessConfig := &compute.AccessConfig{
				Name: "External NAT",
				Type: "ONE_TO_ONE_NAT",
			}
			err := i.AddAccessConfig(instance.Name, instance.Zone, networkInterface, accessConfig)
			if err != nil {
				return err
			}
		}
	} else {
		if instanceExternalIp != "" {
			// TODO: Only if network has no vip
			networkInterface := instance.NetworkInterfaces[0].Name
			accessConfig := instance.NetworkInterfaces[0].AccessConfigs[0].Name
			err := i.DeleteAccessConfig(instance.Name, instance.Zone, networkInterface, accessConfig)
			if err != nil {
				return err
			}
		}
	}

	return nil
}
<commit_msg>Update configure networks<commit_after>package ginstance

import (
	"reflect"
	"sort"

	bosherr "github.com/cloudfoundry/bosh-agent/errors"

	"github.com/frodenas/bosh-google-cpi/api"
	"github.com/frodenas/bosh-google-cpi/google/util"
	"google.golang.org/api/compute/v1"
)

func (i GoogleInstanceService) ConfigureNetworks(id string, instanceNetworks GoogleInstanceNetworks) error {
	instance, found, err := i.Find(id, "")
	if err != nil {
		return err
	}
	if !found {
		return bosherr.Errorf("Google Instance '%s' not found", id)
	}

	if err := i.addToTargetPool(instance, instanceNetworks); err != nil {
		return err
	}

	return nil
}

func (i GoogleInstanceService) addToTargetPool(instance *compute.Instance, instanceNetworks GoogleInstanceNetworks) error {
	targetPoolName := instanceNetworks.TargetPool()

	if targetPoolName != "" {
		err := instanceNetworks.targetPoolService.AddInstance(targetPoolName, instance.SelfLink)
		if err != nil {
			return err
		}
	}

	return nil
}

func (i GoogleInstanceService) UpdateNetworks(id string, instanceNetworks GoogleInstanceNetworks) error {
	instance, found, err := i.Find(id, "")
	if err != nil {
		return err
	}
	if !found {
		return bosherr.Errorf("Google Instance '%s' not found", id)
	}

	if err = i.updateNetwork(instance, instanceNetworks); err != nil {
		return err
	}

	if err = i.updateIpForwarding(instance, instanceNetworks); err != nil {
		return err
	}

	if err = i.updateExternalIp(instance, instanceNetworks); err != nil {
		return err
	}

	if err = i.updateTags(instance, instanceNetworks); err != nil {
		return err
	}

	if err := i.updateTargetPool(instance, instanceNetworks); err != nil {
		return err
	}

	return nil
}

func (i GoogleInstanceService) updateNetwork(instance *compute.Instance, instanceNetworks GoogleInstanceNetworks) error {
	// If the network has changed we need to recreate the VM
	dynamicNetwork := instanceNetworks.DynamicNetwork()
	if gutil.ResourceSplitter(instance.NetworkInterfaces[0].Network) != dynamicNetwork.NetworkName {
		i.logger.Debug(googleInstanceServiceLogTag, "Changing network for Google Instance '%s' not supported", instance.Name)
		return api.NotSupportedError{}
	}

	return nil
}

func (i GoogleInstanceService) updateIpForwarding(instance *compute.Instance, instanceNetworks GoogleInstanceNetworks) error {
	// If IP Forwarding has changed we need to recreate the VM
	if instance.CanIpForward != instanceNetworks.CanIpForward() {
		i.logger.Debug(googleInstanceServiceLogTag, "Changing IP Forwarding for Google Instance '%s' not supported", instance.Name)
		return api.NotSupportedError{}
	}

	return nil
}

func (i GoogleInstanceService) updateExternalIp(instance *compute.Instance, instanceNetworks GoogleInstanceNetworks) error {
	var err error

	vipNetwork := instanceNetworks.VipNetwork()

	if vipNetwork.IP != "" {
		err = i.updateVipAddress(instance, vipNetwork.IP)
	} else {
		err = i.updateEphemeralExternalIp(instance, instanceNetworks)
	}

	if err != nil {
		return err
	}

	return nil
}

func (i GoogleInstanceService) updateVipAddress(instance *compute.Instance, ipAddress string) error {
	var instanceExternalIp, accessConfigName string
	if len(instance.NetworkInterfaces[0].AccessConfigs) > 0 {
		instanceExternalIp = instance.NetworkInterfaces[0].AccessConfigs[0].NatIP
		accessConfigName = instance.NetworkInterfaces[0].AccessConfigs[0].Name
	}

	networkInterface := instance.NetworkInterfaces[0].Name

	if instanceExternalIp == "" || instanceExternalIp != ipAddress {
		if instanceExternalIp != "" {
			i.logger.Debug(googleInstanceServiceLogTag, "Detaching Google Static IP Address '%s' from Google Instance '%s'", instanceExternalIp, instance.Name)
			err := i.DeleteAccessConfig(instance.Name, instance.Zone, networkInterface, accessConfigName)
			if err != nil {
				return err
			}
		}

		accessConfig := &compute.AccessConfig{
			Name:  "External NAT",
			Type:  "ONE_TO_ONE_NAT",
			NatIP: ipAddress,
		}

		i.logger.Debug(googleInstanceServiceLogTag, "Attaching Google Static IP Address '%s' to Google Instance '%s'", ipAddress, instance.Name)
		err := i.AddAccessConfig(instance.Name, instance.Zone, networkInterface, accessConfig)
		if err != nil {
			return err
		}

		return nil
	}

	return nil
}

func (i GoogleInstanceService) updateEphemeralExternalIp(instance *compute.Instance, instanceNetworks GoogleInstanceNetworks) error {
	var instanceExternalIp, accessConfigName string
	if len(instance.NetworkInterfaces[0].AccessConfigs) > 0 {
		instanceExternalIp = instance.NetworkInterfaces[0].AccessConfigs[0].NatIP
		accessConfigName = instance.NetworkInterfaces[0].AccessConfigs[0].Name
	}

	networkInterface := instance.NetworkInterfaces[0].Name

	if instanceNetworks.EphemeralExternalIP() {
		if instanceExternalIp == "" {
			accessConfig := &compute.AccessConfig{
				Name: "External NAT",
				Type: "ONE_TO_ONE_NAT",
			}

			i.logger.Debug(googleInstanceServiceLogTag, "Attaching Ephemeral Google IP Address to Google Instance '%s'", instance.Name)
			err := i.AddAccessConfig(instance.Name, instance.Zone, networkInterface, accessConfig)
			if err != nil {
				return err
			}

			return nil
		} else {
			_, found, err := instanceNetworks.addressService.FindByIP(instanceExternalIp)
			if err != nil {
				return nil
			}

			if found {
				i.logger.Debug(googleInstanceServiceLogTag, "Detaching Google Static IP Address '%s' from Google Instance '%s'", instanceExternalIp, instance.Name)
				err := i.DeleteAccessConfig(instance.Name, instance.Zone, networkInterface, accessConfigName)
				if err != nil {
					return err
				}

				accessConfig := &compute.AccessConfig{
					Name: "External NAT",
					Type: "ONE_TO_ONE_NAT",
				}

				i.logger.Debug(googleInstanceServiceLogTag, "Attaching Ephemeral Google IP Address to Google Instance '%s'", instance.Name)
				err = i.AddAccessConfig(instance.Name, instance.Zone, networkInterface, accessConfig)
				if err != nil {
					return err
				}

				return nil
			}
		}
	} else {
		if instanceExternalIp != "" {
			i.logger.Debug(googleInstanceServiceLogTag, "Detaching Google Static IP Address '%s' from Google Instance '%s'", instanceExternalIp, instance.Name)
			err := i.DeleteAccessConfig(instance.Name, instance.Zone, networkInterface, accessConfigName)
			if err != nil {
				return err
			}
		}

		return nil
	}

	return nil
}

{'fraction_non_alphanumeric': 0.10507426976373244, 'fraction_numerical': 0.0025919649087827734, 'mean_word_length': 4.706484641638225, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6982578', 'n_tokens_mistral': 3318, 'n_tokens_neox': 3027, 'n_words': 757}