Adding update vip operation
diff --git a/openstack/networking/v2/extensions/lbaas/vips/requests.go b/openstack/networking/v2/extensions/lbaas/vips/requests.go
index a75f14f..b2e8233 100644
--- a/openstack/networking/v2/extensions/lbaas/vips/requests.go
+++ b/openstack/networking/v2/extensions/lbaas/vips/requests.go
@@ -99,6 +99,14 @@
 	})
 }
 
+var (
+	errNameRequired         = fmt.Errorf("Name is required")
+	errSubnetIDRequried     = fmt.Errorf("SubnetID is required")
+	errProtocolRequired     = fmt.Errorf("Protocol is required")
+	errProtocolPortRequired = fmt.Errorf("Protocol port is required")
+	errPoolIDRequired       = fmt.Errorf("PoolID is required")
+)
+
 // CreateOpts contains all the values needed to create a new virtual IP.
 type CreateOpts struct {
 	// Required. Human-readable name for the VIP. Does not have to be unique.
@@ -138,14 +146,6 @@
 	AdminStateUp *bool
 }
 
-var (
-	errNameRequired         = fmt.Errorf("Name is required")
-	errSubnetIDRequried     = fmt.Errorf("SubnetID is required")
-	errProtocolRequired     = fmt.Errorf("Protocol is required")
-	errProtocolPortRequired = fmt.Errorf("Protocol port is required")
-	errPoolIDRequired       = fmt.Errorf("PoolID is required")
-)
-
 // Create is an operation which provisions a new virtual IP based on the
 // configuration defined in the CreateOpts struct. Once the request is
 // validated and progress has started on the provisioning process, a
@@ -238,3 +238,65 @@
 	res.Err = err
 	return res
 }
+
+// UpdateOpts contains all the values needed to update an existing virtual IP.
+// Attributes not listed here but appear in CreateOpts are immutable and cannot
+// be updated.
+type UpdateOpts struct {
+	// Human-readable name for the VIP. Does not have to be unique.
+	Name string
+
+	// Required. The ID of the pool with which the VIP is associated.
+	PoolID string
+
+	// Optional. Human-readable description for the VIP.
+	Description string
+
+	// Optional. Omit this field to prevent session persistence.
+	Persistence *SessionPersistence
+
+	// Optional. The maximum number of connections allowed for the VIP.
+	ConnLimit *int
+
+	// Optional. The administrative state of the VIP. A valid value is true (UP)
+	// or false (DOWN).
+	AdminStateUp *bool
+}
+
+// Update is an operation which modifies the attributes of the specified VIP.
+func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult {
+	type vip struct {
+		Name         string              `json:"name,omitempty"`
+		PoolID       string              `json:"pool_id,omitempty"`
+		Description  *string             `json:"description,omitempty"`
+		Persistence  *SessionPersistence `json:"session_persistence,omitempty"`
+		ConnLimit    *int                `json:"connection_limit,omitempty"`
+		AdminStateUp *bool               `json:"admin_state_up,omitempty"`
+	}
+
+	type request struct {
+		VirtualIP vip `json:"vip"`
+	}
+
+	reqBody := request{VirtualIP: vip{
+		Name:         opts.Name,
+		PoolID:       opts.PoolID,
+		Description:  gophercloud.MaybeString(opts.Description),
+		ConnLimit:    opts.ConnLimit,
+		AdminStateUp: opts.AdminStateUp,
+	}}
+
+	if opts.Persistence != nil {
+		reqBody.VirtualIP.Persistence = opts.Persistence
+	}
+
+	var res UpdateResult
+	_, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{
+		MoreHeaders: c.Provider.AuthenticatedHeaders(),
+		ReqBody:     &reqBody,
+		Results:     &res.Resp,
+		OkCodes:     []int{202},
+	})
+
+	return res
+}
diff --git a/openstack/networking/v2/extensions/lbaas/vips/requests_test.go b/openstack/networking/v2/extensions/lbaas/vips/requests_test.go
index 5230eae..d1a145f 100644
--- a/openstack/networking/v2/extensions/lbaas/vips/requests_test.go
+++ b/openstack/networking/v2/extensions/lbaas/vips/requests_test.go
@@ -251,3 +251,53 @@
 	th.AssertEquals(t, 1000, vip.ConnLimit)
 	th.AssertEquals(t, SessionPersistence{Type: "APP_COOKIE", CookieName: "MyAppCookie"}, vip.Persistence)
 }
+
+func TestUpdate(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+
+	th.Mux.HandleFunc("/v2.0/lb/vips/4ec89087-d057-4e2c-911f-60a3b47ee304", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "PUT")
+		th.TestHeader(t, r, "X-Auth-Token", tokenID)
+		th.TestHeader(t, r, "Content-Type", "application/json")
+		th.TestHeader(t, r, "Accept", "application/json")
+		th.TestJSONRequest(t, r, `
+{
+    "vip": {
+        "connection_limit": 1000
+    }
+}
+			`)
+
+		w.Header().Add("Content-Type", "application/json")
+		w.WriteHeader(http.StatusAccepted)
+
+		fmt.Fprintf(w, `
+{
+    "vip": {
+        "status": "PENDING_UPDATE",
+        "protocol": "HTTP",
+        "description": "",
+        "admin_state_up": true,
+        "subnet_id": "8032909d-47a1-4715-90af-5153ffe39861",
+        "tenant_id": "83657cfcdfe44cd5920adaf26c48ceea",
+        "connection_limit": 1000,
+        "pool_id": "61b1f87a-7a21-4ad3-9dda-7f81d249944f",
+        "address": "10.0.0.11",
+        "protocol_port": 80,
+        "port_id": "f7e6fe6a-b8b5-43a8-8215-73456b32e0f5",
+        "id": "c987d2be-9a3c-4ac9-a046-e8716b1350e2",
+        "name": "NewVip"
+    }
+}
+		`)
+	})
+
+	i1000 := 1000
+	options := UpdateOpts{ConnLimit: &i1000}
+	vip, err := Update(serviceClient(), "4ec89087-d057-4e2c-911f-60a3b47ee304", options).Extract()
+	th.AssertNoErr(t, err)
+
+	th.AssertEquals(t, "PENDING_UPDATE", vip.Status)
+	th.AssertEquals(t, 1000, vip.ConnLimit)
+}