Example #1
0
// waitForToken uses `cmd.Until` to wait for the service account controller to fulfill the token request
func waitForToken(token *api.Secret, serviceAccount *api.ServiceAccount, timeout time.Duration, client unversioned.SecretsInterface) (*api.Secret, error) {
	// there is no provided rounding function, so we use Round(x) === Floor(x + 0.5)
	timeoutSeconds := int64(math.Floor(timeout.Seconds() + 0.5))

	options := api.ListOptions{
		FieldSelector:   fields.SelectorFromSet(fields.Set(map[string]string{"metadata.name": token.Name})),
		Watch:           true,
		ResourceVersion: token.ResourceVersion,
		TimeoutSeconds:  &timeoutSeconds,
	}

	watcher, err := client.Watch(options)
	if err != nil {
		return nil, fmt.Errorf("could not begin watch for token: %v", err)
	}

	event, err := cmd.Until(timeout, watcher, func(event watch.Event) (bool, error) {
		if event.Type == watch.Error {
			return false, fmt.Errorf("encountered error while watching for token: %v", event.Object)
		}

		eventToken, ok := event.Object.(*api.Secret)
		if !ok {
			return false, nil
		}

		if eventToken.Name != token.Name {
			return false, nil
		}

		switch event.Type {
		case watch.Modified:
			if serviceaccounts.IsValidServiceAccountToken(serviceAccount, eventToken) {
				return true, nil
			}
		case watch.Deleted:
			return false, errors.New("token was deleted before fulfillment by service account token controller")
		case watch.Added:
			return false, errors.New("unxepected action: token was added after initial creation")
		}
		return false, nil
	})
	if err != nil {
		return nil, err
	}

	return event.Object.(*api.Secret), nil
}
Example #2
0
func DeleteAndWaitForNamespaceTermination(c *kclient.Client, name string) error {
	w, err := c.Namespaces().Watch(kapi.ListOptions{})
	if err != nil {
		return err
	}
	if err := c.Namespaces().Delete(name); err != nil {
		return err
	}
	_, err = cmd.Until(30*time.Second, w, func(event watch.Event) (bool, error) {
		if event.Type != watch.Deleted {
			return false, nil
		}
		namespace, ok := event.Object.(*kapi.Namespace)
		if !ok {
			return false, nil
		}
		return namespace.Name == name, nil
	})
	return err
}