func (r *Firewall) Actual(immutable *cluster.Cluster) (*cluster.Cluster, cloud.Resource, error) {
	logger.Debug("firewall.Actual")

	newResource := defaultFirewallStruct()
	// Digital Firewalls.Get requires firewall ID, which we will not always have.thats why using List.
	firewalls, _, err := Sdk.Client.Firewalls.List(context.TODO(), &godo.ListOptions{})
	if err != nil {
		return nil, nil, fmt.Errorf("failed to get firwalls info")
	}
	for _, firewall := range firewalls {
		if firewall.Name == r.Name { // In digitalOcean Firwall names are unique.
			// gotcha get all details from this firewall and populate actual.
			firewallBytes, err := json.Marshal(firewall)
			if err != nil {
				return nil, nil, fmt.Errorf("failed to marshal DO firewall details err: %v", err)
			}
			if err := json.Unmarshal(firewallBytes, newResource); err != nil {
				return nil, nil, fmt.Errorf("failed to unmarhal DO firewall details err: %v", err)
			}
			// hack: DO api doesn't take "0" as portRange, but returns "0" for port range in firewall.List.
			for i := 0; i < len(newResource.OutboundRules); i++ {
				if newResource.OutboundRules[i].PortRange == "0" {
					newResource.OutboundRules[i].PortRange = "all"
				}
			}
			for i := 0; i < len(newResource.InboundRules); i++ {
				if newResource.InboundRules[i].PortRange == "0" {
					newResource.InboundRules[i].PortRange = "all"
				}
			}
		}
	}

	newCluster := r.immutableRender(newResource, immutable)
	return newCluster, newResource, nil
}
func (r *Firewall) Actual(immutable *cluster.Cluster) (*cluster.Cluster, cloud.Resource, error) {
	logger.Debug("firewall.Actual")

	newResource := defaultFirewallStruct()
	
	firewalls, _, err := Sdk.Client.Firewalls.List(context.TODO(), &godo.ListOptions{})
	if err != nil {
		return nil, nil, fmt.Errorf("failed to get firwalls info")
	}
	for _, firewall := range firewalls {
		if firewall.Name == r.Name { 
			
			firewallBytes, err := json.Marshal(firewall)
			if err != nil {
				return nil, nil, fmt.Errorf("failed to marshal DO firewall details err: %v", err)
			}
			if err := json.Unmarshal(firewallBytes, newResource); err != nil {
				return nil, nil, fmt.Errorf("failed to unmarhal DO firewall details err: %v", err)
			}
			
			for i := 0; i < len(newResource.OutboundRules); i++ {
				if newResource.OutboundRules[i].PortRange == "0" {
					newResource.OutboundRules[i].PortRange = "all"
				}
			}
			for i := 0; i < len(newResource.InboundRules); i++ {
				if newResource.InboundRules[i].PortRange == "0" {
					newResource.InboundRules[i].PortRange = "all"
				}
			}
		}
	}

	newCluster := r.immutableRender(newResource, immutable)
	return newCluster, newResource, nil
}
func ( r * Firewall ) Actual ( immutable * cluster . Cluster ) ( * cluster . Cluster , cloud . Resource , error ) { logger . Debug ( " " ) newResource := defaultFirewallStruct ( ) // Digital Firewalls.Get requires firewall ID, which we will not always have.thats why using List. firewalls , _ , err := Sdk . Client . Firewalls . List ( context . TODO ( ) , & godo . ListOptions { } ) if err != nil { return nil , nil , fmt . Errorf ( " " ) } for _ , firewall := range firewalls { if firewall . Name == r . Name { // In digitalOcean Firwall names are unique. // gotcha get all details from this firewall and populate actual. firewallBytes , err := json . Marshal ( firewall ) if err != nil { return nil , nil , fmt . Errorf ( " " , err ) } if err := json . Unmarshal ( firewallBytes , newResource ) ; err != nil { return nil , nil , fmt . Errorf ( " " , err ) } // hack: DO api doesn't take "0" as portRange, but returns "0" for port range in firewall.List. for i := 0 ; i < len ( newResource . OutboundRules ) ; i ++ { if newResource . OutboundRules [ i ] . PortRange == " " { newResource . OutboundRules [ i ] . PortRange = " " } } for i := 0 ; i < len ( newResource . InboundRules ) ; i ++ { if newResource . InboundRules [ i ] . PortRange == " " { newResource . InboundRules [ i ] . PortRange = " " } } } } newCluster := r . immutableRender ( newResource , immutable ) return newCluster , newResource , nil }
// Actual calls DO firewall Api and returns the actual state of firewall in the cloud.
Actual calls DO firewall Api and returns the actual state of firewall in the cloud .