GithubHelp home page GithubHelp logo

f5networks / cf-bigip-ctlr Goto Github PK

View Code? Open in Web Editor NEW
2.0 24.0 13.0 6.51 MB

The F5 BIG-IP Controller for Cloud Foundry makes the F5 BIG-IP Local Traffic Manager services available to applications running in the Cloud Foundry platform.

License: Apache License 2.0

Makefile 0.56% Ruby 0.28% Shell 2.32% Go 95.28% Python 1.55%

cf-bigip-ctlr's Introduction

Build Status Slack Coverage Status

F5 BIG-IP Controller for Cloud Foundry

This GitHub repository has been archived and is read-only. This project is no longer actively maintained.

The F5 BIG-IP Controller for Cloud Foundry makes the F5 BIG-IP [Local Traffic Manager](<https://f5.com/products/big-ip/local-traffic-manager-ltm) services available to applications running in the Cloud Foundry platform.

Documentation

For instructions on how to use this component, use the F5 BIG-IP Controller for Cloud Foundry docs.

For guides on this and other solutions for Cloud Foundry, see the F5 Solution Guides for Cloud Foundry.

Getting Help

We encourage you to use the cc-cloudfoundry channel in our f5CloudSolutions Slack workspace for discussion and assistance on this controller. This channel is typically monitored Monday-Friday 9am-5pm MST by F5 employees who will offer best-effort support.

Contact F5 Technical support via your typical method for more time sensitive changes and other issues requiring immediate support.

Running

The official docker image is f5networks/cf-bigip-ctlr.

Usually, the controller is deployed in Cloud Foundry. However, the controller can be run locally for development testing. The controller requires a running NATS server, without a valid connection the controller will not start. The controller can either be run against a gnatsd server or standalone against a Cloud Foundry installation.

Option gnatsd:

  • Go should be installed and in the PATH
  • GOPATH should be set as described in http://golang.org/doc/code.html
  • Pip install the python/cf-runtime-requirements.txt into a virtualenv of your choice
workon cf-bigip-ctlr
pip install -r python/cf-runtime-requirements.txt
  • gnatds installed and in the PATH
go get github.com/nats-io/gnatsd
gnatsd &
  • Optionally run unit tests
go get github.com/onsi/ginkgo
go get github.com/onsi/gomega
ginkgo -keepGoing -trace -p -progress -r -failOnPending -randomizeAllSpecs -race
go install
  • Update BIGIP_CTLR_CFG environment variable for your specific environment as described in "Configuration"
  • Run the controller
cf-bigip-ctlr

Option standalone:

  • Go should be installed and in the PATH
  • GOPATH should be set as described in http://golang.org/doc/code.html
  • Pip install the python/cf-runtime-requirements.txt into a virtualenv of your choice
workon cf-bigip-ctlr
pip install -r python/cf-runtime-requirements.txt
  • Optionally run unit tests
go get github.com/onsi/ginkgo
go get github.com/onsi/gomega
ginkgo -keepGoing -trace -p -progress -r -failOnPending -randomizeAllSpecs -race
go install
  • Update configuration file or BIGIP_CTLR_CFG environment variable for your specific environment as described in "Configuration"
  • Run the controller
cf-bigip-ctlr -c [CONFIG_FILE]

Building

The official images are built using docker, but standard go build tools can be used for development purposes as described above.

Official Build

Prerequisites:

  • Docker
git clone https://github.com/F5Networks/cf-bigip-ctlr.git
cd cf-bigip-ctlr

# Use docker to build the release artifacts into a local "_docker_workspace" directory and push into docker images
make prod

Alternate, unofficial build

A normal go and godep toolchain can be used as well

Prerequisites:

  • go 1.7
  • GOPATH pointing at a valid go workspace
  • godep (Only needed to modify vendor's packages)
  • python
  • virtualenv
mkdir -p $GOPATH/src/github.com/F5Networks
cd $GOPATH/src/github.com/F5Networks
git clone https://github.com/F5Networks/cf-bigip-ctlr.git
cd cf-bigip-ctlr

# Building all packages, and run unit tests
make prod

Configuration

When pushing the controller into a Cloud Foundry environment a configuration must be passed via the application manifest. An example manifest is located in the docs/_static/config_examples directory.

Update required sections for environment:

  • nats: leave empty for gnatsd otherwise update with CF installed NATS information
  • bigip: leave empty if no BIG-IP is required otherwise update with BIG-IP information
  • routing_api: only required if routing API access is required (TCP routing with route_mode set to all, or tcp)
  • oauth: only required if routing API access is required (TCP routing with route_mode set to all, or tcp)

On startup, the controller will get the BIGIP_CTLR_CFG variable from the environment; setting this variable via an application manifest is required, environment parameters are set in the manifest env section. The controller also supports Cloud Foundry health checks. These can be configured in the manifest fields: health-check-type, and health-check-http-endpoint. In order to configure health checking of the controller use these settings:

health-check-type: http
health-check-http-endpoint: /health

To explore what other settings are available refer to the Cloud Foundry documentation Deploying with Application Manifests.

A minimal configuration manifest to support HTTP routing mode would be written as such (route_mode set to 'http'):

applications:
  - name: cf-bigip-ctlr
    health-check-type: http
    health-check-http-endpoint: /health
    env:
      BIGIP_CTLR_CFG: |
                      bigip:
                        url: https://bigip.example.com
                        user: admin
                        pass: password
                        partition:
                          - example
                        external_addr: 192.168.1.1
                      nats:
                        - host: 192.168.10.1
                          port: 4222
                          user: nats
                          pass: nats-password
                      route_mode: http

If TCP routing is required, the oauth and routing_api sections are required but not the nats section. Set route_mode to 'tcp'.

If both modes are required, the oauth, routing_api, and nats sections are required. Set route_mode to 'all'.

Development

Note: This repository should be imported as github.com/F5Networks/cf-bigip-ctlr.

Dynamic Routing Table

The controller's routing table is updated dynamically via the NATS message bus. NATS can be deployed via BOSH with (cf-release) or standalone using nats-release.

To add or remove a record from the routing table, a NATS client must send register or unregister messages. Records in the routing table have a maximum TTL of 120 seconds, so clients must heartbeat registration messages periodically; we recommend every 20s. Route Registrar is a BOSH job that comes with Routing Release that automates this process.

When deployed with Cloud Foundry, registration of routes for apps pushed to CF occurs automatically without user involvement. For details, see Routes and Domains.

Registering Routes via NATS

When the controller starts, it sends a router.start message to NATS. This message contains an interval that other components should then send router.register on, minimumRegisterIntervalInSeconds. It is recommended that clients should send router.register messages on this interval. This minimumRegisterIntervalInSeconds value is configured through the start_response_delay_interval configuration property. The controller will prune routes that it considers to be stale based upon a separate "staleness" value, droplet_stale_threshold, which defaults to 120 seconds. The controller will check if routes have become stale on an interval defined by prune_stale_droplets_interval, which defaults to 30 seconds. All of these values are represented in seconds and will always be integers.

The format of the router.start message is as follows:

{
  "id": "some-router-id",
  "hosts": ["1.2.3.4"],
  "minimumRegisterIntervalInSeconds": 20,
  "prunteThresholdInSeconds": 120,
}

After a router.start message is received by a client, the client should send router.register messages. This ensures that the new controller can update its routing table.

If a component comes online after the controller, it must make a NATS request called router.greet in order to determine the interval. The response to this message will be the same format as router.start.

The format of the router.register message is as follows:

{
  "host": "127.0.0.1",
  "port": 4567,
  "uris": [
    "my_first_url.vcap.me",
    "my_second_url.vcap.me"
  ],
  "tags": {
    "another_key": "another_value",
    "some_key": "some_value"
  },
  "app": "some_app_guid",
  "stale_threshold_in_seconds": 120,
  "private_instance_id": "some_app_instance_id",
  "router_group_guid": "some_router_group_guid"
}

stale_threshold_in_seconds is the custom staleness threshold for the route being registered. If this value is not sent, it will default to the controller's default staleness threshold.

app is a unique identifier for an application that the endpoint is registered for.

private_instance_id is a unique identifier for an instance associated with the app identified by the app field.

router_group_guid determines which controllers will register route. Only controllers configured with the matching router group will register the route. If a value is not provided, the route will be registered by all controllers that have not be configured with a router group.

Such a message can be sent to both the router.register subject to register URIs, and to the router.unregister subject to unregister URIs, respectively.

Note: In order to use nats-pub to register a route, you must run the command on the NATS VM. If you are using cf-deployment, you can run nats-pub from any VM.

cf-bigip-ctlr's People

Contributors

aaronshurley avatar abbyachau avatar amudukutore avatar atulkc avatar bluesalt avatar crhino avatar dramich avatar edarzins avatar emalm avatar f5yacobucci avatar flawedmatrix avatar fordaz avatar jfmyers9 avatar jputrino avatar julz avatar leochu avatar luan avatar markstgodard avatar mmb avatar msmykowski avatar pietern avatar recursivelycurious avatar russokj avatar ryan-talley avatar shalako avatar swetharepakula avatar vito avatar yuzhangcmu avatar zaksoup avatar zrob avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cf-bigip-ctlr's Issues

Controller fails to reconfigure Big-IP if restarted with new external address

Reproduce:

  • Configure controller and deploy in cloud foundry
  • Verify objects are creates: VIP, VirtAddr, etc.
  • Change external_addr in manifest config
  • Re-push cf-bigip-ctlr

The new controller will fail removing the previous VIP as it can't delete with an attached virtual address - SDK Bad Request error.

Note: this may be fixed with the CCCL updates, but regardless this error should generate a test case that reconfigures cf-bigip-ctlr and redeploys.

tier2_ip_range needs more robust validation

Description

Currently the tier2_ip_range config parameter is only validated as being a properly formatted CIDR block. However, it can be very easy as a user to misconfigure this parameter causing errors on the BIG-IP creation of tier2 VIPs. Prefixes should be evaluated to see if they fall on CIDR block boundaries when users a trying to define networks with their tier2_ip_range.

Controller Version

v1.1

"next release" showing up on Release Notes page

Description

See http://clouddocs.f5.com/products/connectors/cf-bigip-ctlr/v1.1/RELEASE-NOTES.html

"next-release" and "Bug Fixes" should not be showing up in the published doc.

Kubernetes Version

N/A

Controller Version

v1.1

BIG-IP Version

N/A

Diagnostic Information

<Configuration files, error messages, logs>
Note: Sanitize the data. For example, be mindful of IPs, ports, application names and URLs
Note: The following F5 article outlines the information required when opening an issue.
https://support.f5.com/csp/article/K60974137

README.rst user docs do not adequately explain configuration manifest

While the README.rst does include an extensive section describing the configuration parameters it's unclear how those parameters are delivered to the application.

Add section or verbage describing the recommended method of using a cloud foundry manifest file. That the parameters MUST be added to the 'env' section under the var BIGIP_CTLR_CFG in a yaml formatted string.

Mention other important manifest inputs outside of environment parameters: 'name', 'health-check-type', 'health-check-http-endpoint'.

Add TCP profile to virtuals as default

Currently only the http profile is being set on virtuals, tcp also needs to be added. The BIG-IP adds tcp profile so the diff in cccl sees a difference and rewrite a virtual every pass. This causes extra writes to the BIG-IP and logs.

Update python code to address flake8 failures

When using latest flake8 (3.5) the following failures happen:
./bigipconfigdriver.py:627:5: E722 do not use bare except' ./tests/test_bigipconfigdriver.py:722:9: E722 do not use bare except' ./tests/test_bigipconfigdriver.py:907:9: E722 do not use bare except'

Update the python code to address this.

Upgrade to new ctlr version causes python exception

Description

The addition of the metadata field, and improper list handling in CCCL, results in an exception when upgrading the controller to a new version to manage resources created by an older version.

Controller Version

1.2

Controller does not handle all permutations of wildcard routes

A wildcard route of foo*.cf.com will cause a configuration attempt for a pool named: foo*-SHA256HASH. Big-IP refuses this name as asterisk '*' is an invalid character.

Presumably routes of f*o.cf.com and *foo.cf.com will have the same issue.

The controller should identify these routes as wildcard and configure the appropriate startsWith, endsWith rules depending on the asterisk placement and finally name the pool with a Big-IP compatible name.

There should be an f5router.makeVirtual function

Description

There is a lot of duplicated code in f5router, httpUpdate, tcpUpdate... that all declare virtual structs. Instead of this follow the pool declaration pattern where there is a makePool function in f5router that the other packages can call. So go from vs = &bigipResources.Virtual{...} to vs = makeVirtual.

Controller Version

v1.1

f5router logging is inconsistent

Description

The logging in f5router.go is inconsistent with some messages containing "f5router" while others do not. These should be fixed so that they either consistently do or do not contain f5router.

Add a mapping of the route/pool hash to cf route

A cf admin needs a way to easily map a route to the rule and pool created on the bigip. This can be done by adding the route to the description field of the rule and and the pool plus adding a log message. It would also be helpful to add this info to the /routes endpoint for debugging.

Clarify what BIG-IP load balancing algorithms the Controller supports

Description

In the docs/README, the [#lb] footnote should clarify that the ctlr only supports algorithms that don't require additional input.

E.g.:

.. [#lb] The Controller supports load balancing algorithms that don't require additional user input. See "BIG-IP system load balancing methods" in the BIG-IP Local Traffic Management Basics user guide for more information.

Cloud Foundry Version

N/A

Controller Version

1.0

BIG-IP Version

N/A

Use Partitions everywhere

Update config to use partitions in all locations. Currently the config property 'Partitions' uses 'partition' for json and 'partitions' for yaml, this needs to be updated to be 'partitions' in all locations.

Need to support yaml and json strings for SERVICE_BROKER_CONFIG

Description

Currently the SERVICE_BROKER_CONFIG config parameter only accepts a JSON encoded string as its argument, but the SERVICE_BROKER_CFG config parameter accepts both JSON and YAML. In order to be consistent SERVICE_BROKER_CONFIG should also support YAML formatted strings.

Controller Version

v1.1

Unit test failure: test_confighandler_backoff_time

Occurred in forked repo but up to date with F5Networks/cf-bigip-ctlr:master: c97522b


_______________________ test_confighandler_backoff_time ________________________

request = <FixtureRequest for <Function 'test_confighandler_backoff_time'>>

    def test_confighandler_backoff_time(request):

        try:

            handler = bigipconfigdriver.ConfigHandler({}, {}, 0.25)

            backoff = handler.handle_backoff

            handler._backoff_time = .025

            handler._max_backoff_time = .1

    

            backoff()

            # first call doubles _backoff_time _backoff_timer should have original

            # value for its interval

            assert handler._backoff_timer.interval == .025

            assert handler._backoff_time == .05

            backoff()

            # values should not change since we already have a timer set

            assert handler._backoff_timer.interval == .025

[1m            assert handler._backoff_time == .05

            handler._backoff_timer = None

            backoff()

            # call doubles _backoff_time since we cleared previous timer

            assert handler._backoff_timer.interval == .05

            assert handler._backoff_time == .1

            handler._backoff_timer = None

            backoff()

            # hit _max_backoff_time so _backoff_time does not increase

            assert handler._backoff_timer.interval == .1

            assert handler._backoff_time == .1

    

        finally:

>           handler.stop()

backoff    = <bound method ConfigHandler.handle_backoff of <python.bigipconfigdriver.ConfigHandler instance at 0x7faed98fe3b0>>

handler    = <python.bigipconfigdriver.ConfigHandler instance at 0x7faed98fe3b0>

request    = <FixtureRequest for <Function 'test_confighandler_backoff_time'>>

tests/test_bigipconfigdriver.py:1241: 

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

bigipconfigdriver.py:615: in stop

    self.cleanup_backoff()

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <python.bigipconfigdriver.ConfigHandler instance at 0x7faed98fe3b0>

    def cleanup_backoff(self):

        """Cleans up canceled backoff timers."""

        self._backoff_timer.cancel()

>       self._backoff_timer.join()

E       AttributeError: 'NoneType' object has no attribute 'join'

self       = <python.bigipconfigdriver.ConfigHandler instance at 0x7faed98fe3b0>

bigipconfigdriver.py:734: AttributeError

Move to GitHub (once releasable & approved for licensing)

As a peer to the k8s-bigip-controller and marathon-bigip-controller we anticipate this repo will also be moved to github.

Timing of that move is dependent a bit on speed of development to a releasable state and on licensing / legal review.

This issue is a place holder.

Controller Environment Variable Names are Inconsistent

Description

The controller currently uses to environment variables to handle configuration: BIGIP_CTLR_CFG for controller config and SERVICE_BROKER_CONFIG for (optional) service broker config. These should be renamed to be consistent either use CFG or CONFIG for both.

Controller stops updating BIG-IP configuration after an exception occurs in the python driver

Description

If the bigipdriver.py process encounters an exception in the _do_reset thread, then the thread dies and no longer processes updates to the config file. The front-end controller is unaware of this and keeps updating the config file. Many of these exceptions are transient in nature and the python driver should handle them gracefully.

Diagnostic Information

Typical log file has an error similar to the following:

21:55:44 2018/01/23 04:53:31 [INFO] Traceback (most recent call last):
21:55:44 2018/01/23 04:53:31 [INFO]   File "/opt/rh/python27/root/usr/lib64/python2.7/threading.py", line 804, in __bootstrap_inner
21:55:44 2018/01/23 04:53:31 [INFO]     self.run()
21:55:44 2018/01/23 04:53:31 [INFO]   File "/opt/rh/python27/root/usr/lib64/python2.7/threading.py", line 757, in run
21:55:44 2018/01/23 04:53:31 [INFO]     self.__target(*self.__args, **self.__kwargs)
21:55:44 2018/01/23 04:53:31 [INFO]   File "/app/python/bigipconfigdriver.py", line 320, in _do_reset
21:55:44 2018/01/23 04:53:31 [INFO]     config = _parse_config(self._config_file)
21:55:44 2018/01/23 04:53:31 [INFO]   File "/app/python/bigipconfigdriver.py", line 584, in _parse_config
21:55:44 2018/01/23 04:53:31 [INFO]     config_json = json.load(config)
21:55:44 2018/01/23 04:53:31 [INFO]   File "/opt/rh/python27/root/usr/lib64/python2.7/json/__init__.py", line 291, in load
21:55:44 2018/01/23 04:53:31 [INFO]     **kw)
21:55:44 2018/01/23 04:53:31 [INFO]   File "/opt/rh/python27/root/usr/lib64/python2.7/json/__init__.py", line 339, in loads
21:55:44 2018/01/23 04:53:31 [INFO]     return _default_decoder.decode(s)
21:55:44 2018/01/23 04:53:31 [INFO]   File "/opt/rh/python27/root/usr/lib64/python2.7/json/decoder.py", line 364, in decode
21:55:44 2018/01/23 04:53:31 [INFO]     obj, end = self.raw_decode(s, idx=_w(s, 0).end())
21:55:44 2018/01/23 04:53:31 [INFO]   File "/opt/rh/python27/root/usr/lib64/python2.7/json/decoder.py", line 382, in raw_decode
21:55:44 2018/01/23 04:53:31 [INFO]     raise ValueError("No JSON object could be decoded")
21:55:44 2018/01/23 04:53:31 [INFO] ValueError: No JSON object could be decoded
21:55:44 2018/01/23 04:53:31 [INFO] [2018-01-23 04:53:31,065 __main__ INFO] entering inotify loop to watch /tmp/k8s-bigip-ctlr.config553021570/config.json
21:55:44 2018/01/23 04:53:31 [INFO] 

dockerhub should include `latest` tag

The default pull <namespace>/<orchestration>-bigip-ctlr looks for latest and existing CI does not include an "image only" tag to ensure that <namespace>/<orchestration>-bigip-ctlr:latest is available.

sslProfiles option not documented

The docs at https://github.com/F5Networks/cf-bigip-ctlr/blob/master/README.md don't document the option to attach SSL profile, only the option to attach profiles.

Update the docs to document the sslProfile option. We should also document how we deal with SSL generally, covering at least these points:

  • If you do not attach anything via the sslProfile option, then we will only create the HTTP port 80 virtual server.
  • If you do attach an sslProfile via the sslProfile option, then we will create an HTTP port 80 and HTTPS port 443 virtual server.
  • You can attach multiple certificate/key pairs to an sslProfile. The BIG-IP will use TLS Server Name Indication (SNI) to choose the correct certificate to present to the client. This is used to support multiple hostnames (foo.mypcf.com and bar.mypcf.com) in the same CloudFoundry instance. Some of these cert/key pairs can be wildcard (*.mypcf.com).
  • The profiles option should be used for any non-SSL profiles that you would like the cf-bigip-ctlr to attach on your behalf (for example TCP acceleration profiles).

Change behavior of controller on startup when encountering errors

Description
The controller currently exits if the cccl driver (bigipconfigdriver.py) encounters any exceptions during startup. It should ignore transient errors just like it would during the main processing loop.

Cloud Foundary Version

Controller Version
1.1

BIG-IP Version
12.1

Diagnostics

Document partition management and configuration enforcement

The CC will enforce orchestration configuration on the managed partition. Our meaning of "managed partition" includes the enforce of configuration; in other words, objects may be created, deleted, updated after administrator changes based on the authoritative configuration coming from the environment.

The consequences of this could mean disruptions of service and unexpected behavior.

Clearly document that administrator changes in the CC managed partition will result in BIG-IP configuration changes back to the state it expects.
NOTE: all CCs exhibit this behavior. Ensure consistency of language across each.

Clarify tier2_ip_range description

Description

Update this language: IP range to assign to the tier2 vips (required in Service Broker mode only)

Since we've made this optional it's always optional, "used in Service Broker mode only" makes more sense to me; docs/README.rst

Cloud Foundry Version

n/a

Controller Version

n/a

BIG-IP Version

n/a

Diagnostic Information

n/a - just a doc clarification

New tier2_ip_range parameter breaks backward compatibility

Description

Users cannot upgrade to version 1.1 without changing their configuration. The tier2_ip_range should not be a required parameter.

There should be a sane default for this parameter.

Cloud Foundry Version

N/A

Controller Version

1.1

BIG-IP Version

N/A

Diagnostic Information

Finish docs config

  • Add the docs build and deploy sections to .gitlab-ci.yml
  • Add the docs/_build directory to .gitignore.

Controller error on published policy

If you manually publish the policy through the bigip gui that the controller is in charge of the status changes and the controller can no longer publish the policy.

Policy only controller has touched:
"status": "legacy",
Policy published through GUI:
"status": "published",

Error seen:
Cannot create/modify published policy \'/cf/cf-routing-policy\' directly, try specifying a draft folder like \'/cf/Drafts/cf-routing-policy\'

Note: this may be fixed with the CCCL updates, but regardless this error should generate a test case that reconfigures cf-bigip-ctlr and redeploys.

Add 'go badge' and address score

Using this report card, update the repo to address issues found in the report card (where it makes sense) then possibly add the badge to the README.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.