Issues regarding Management API over Ziti cli

Hi , I was trying to bring the things I did with ziti cli (such as creating private routers , services , policies.. etc) via API . In this case its management API

I have deployed the router in postgres host and tried to create identities , services everything via API .

Status of the things done:
I was able to see the router is online ,
I was not able to see terminators for services .

Please either point the issue or guide me how to debug it .

Following are the steps I did :

export ZITI_URL="https://<my_ziti_url>:1280"
export USERNAME="admin"
export password=$(kubectl get secrets "ziti-controller-admin-secret" \
--namespace "ziti" \
--output go-template='{{index .data "admin-password" | base64decode }}')

response=$(curl -s -X POST "$ZITI_URL/edge/management/v1/authenticate?method=password" \
-H "Content-Type: application/json" \
-d "{\"username\": \"$USERNAME\", \"password\": \"$password\"}" --insecure)

# Extract the session token from the response
session=$(echo $response | jq -r '.data.token')

## created router in postgres host 

routerName="router-test6"
roleAttributes=("router-group-test")
isTunnelerEnabled=true  # Set this to true

# Create the edge router identity
routerResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/edge-routers" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "'"$routerName"'",
    "roleAttributes": ["'"${roleAttributes[@]}"'"],
    "isTunnelerEnabled": '$isTunnelerEnabled'
  }' --insecure)

# Output the created edge router details
echo "Created Edge Router:"
echo "$routerResponse" | jq

edgeRouterId=$(echo $edgeRouterResponse | jq -r '.data.id')

echo "routerID is $edgeRouterId"

edgeRouterResponse=$(curl -s -X GET "$edgeRouterEndpoint" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  --insecure)

enrollmentJwt=$(echo $edgeRouterResponse | jq -r '.data.enrollmentJwt')  
## used this jwt for running the router and the router is online

# -------------------------

# Example usage of variables in curl commands
# Create Identity
IdentityName=client-6
ClientAttribute=client-group-6

IdentityResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/identities" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "'"$IdentityName"'",
    "isAdmin": false,
    "type": "User",
    "roleAttributes": ["'"$ClientAttribute"'"],
    "enrollment": {
      "type": "OTT"  
    }
  }' --insecure)

# Extract Identity ID
ClientId=$(echo $IdentityResponse | jq -r .data.id)

## jR5BRdjpG

enrollmentsEndpoint="$ZITI_URL/edge/management/v1/enrollments"

# Example enrollment data (adjust as per your requirements)
enrollmentData='{
  "expiresAt": "2024-08-24T14:15:22Z",
  "identityId": "'"$ClientId"'",
  "method": "ott"
}'

# Create enrollment
enrollmentResponse=$(curl -s -X POST "$enrollmentsEndpoint" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d "$enrollmentData" \
  --insecure)

# Extract the enrollment ID from the response
enrollmentId=$(echo $enrollmentResponse | jq -r '.data.id')

# Retrieve enrollment details to get the JWT token
enrollmentDetailsEndpoint="$enrollmentsEndpoint/$enrollmentId"
enrollmentDetailsResponse=$(curl -s -X GET "$enrollmentDetailsEndpoint" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  --insecure)

# Extract the JWT token from enrollmentDetailsResponse using jq
jwtToken=$(echo $enrollmentDetailsResponse | jq -r '.data.jwt')

# Output the JWT token
echo "JWT Token: $jwtToken"

curl -s -X GET "$ZITI_URL/edge/management/v1/config-types" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  --insecure | jq '.data[] | select(.name == "host.v1")'

# Create Intercept Config
interceptConfigResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/configs" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "service-6-intercept",
    "configTypeId": "g7cIWbcGg",
    "data": {
      "protocols": ["tcp"],
      "addresses": ["post.ziti.internal"],
      "portRanges": [{"low": 5432, "high": 5432}]
    }
  }' --insecure)

interceptConfigId=$(echo $interceptConfigResponse | jq -r '.data.id')

echo "Intercept Config is $interceptConfigId"

## Intercept Config is R15ZcOGsxKWvVgiy0EwCL


# Create Host Config
hostConfigResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/configs" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "service-6-host",
    "configTypeId": "NH5p4FpGR",
    "data": {
      "protocol": "tcp",
      "address": "localhost",
      "port": 5432
    }
  }' --insecure)

hostConfigId=$(echo $hostConfigResponse | jq -r '.data.id')

echo "host Config is $hostConfigId"

# host Config is 2Ad5hcUg1Nfd8G1ESKW8tM

# Create Service
serviceResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/services" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "service-6",
    "configs": ["R15ZcOGsxKWvVgiy0EwCL", "2Ad5hcUg1Nfd8G1ESKW8tM"],
    "encryptionRequired": true
  }' --insecure)

serviceId=$(echo $serviceResponse | jq -r '.data.id')
# 1Oh311d9m0gm2vUET6cjya

# Create Dial Policy
createDialPolicyResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/service-policies" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "service-6-dial-policy",
    "type": "Dial",
    "semantic": "AllOf",
    "serviceRoles": ["#all"],
    "identityRoles": ["#client-group-6"]
  }' --insecure)

echo "$createDialPolicyResponse" | jq 

# 39ZQKEsWgoDKVzCDHZP66E

# Create Bind Policy
createBindPolicyResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/service-policies" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "service-6-bind-policy",
    "type": "Bind",
    "semantic": "AllOf",
    "serviceRoles": ["#all"],
    "identityRoles": ["#router-group-test"]
  }' --insecure)

echo "$createBindPolicyResponse" | jq 

# 45dOY2KZQFMOMF1uxcuJ97


# Retrieve terminators associated with the service ID
terminatorsResponse=$(curl -s -X GET "$ZITI_URL/edge/management/v1/services/1Oh311d9m0gm2vUET6cjya/terminators" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" --insecure)

# Output the terminators
echo "$terminatorsResponse" | jq .data
# [] 

Making GET request to

$ZITI_URL/edge/management/v1/identities/jR5BRdjpG/policy-advice/1Oh311d9m0gm2vUET6cjya I get

{
    "data": {
      "commonRouters": [
        {
          "_links": {
            "edge-router-policies": {
              "href": "./edge-routers/y6PWYnjpG/edge-router-policies"
            },
            "self": {
              "href": "./edge-routers/y6PWYnjpG"
            }
          },
          "entity": "edge-routers",
          "id": "y6PWYnjpG",
          "name": "router-test6",
          "isOnline": true
        }
      ],
      "identity": {
        "_links": {
          "auth-policies": {
            "href": "./auth-policies/default"
          },
          "authenticators": {
            "href": "./identities/jR5BRdjpG/authenticators"
          },
          "edge-router-policies": {
            "href": "./identities/jR5BRdjpG/edge-router-policies"
          },
          "edge-routers": {
            "href": "./identities/jR5BRdjpG/edge-routers"
          },
          "enrollments": {
            "href": "./identities/jR5BRdjpG/enrollments"
          },
          "failed-service-requests": {
            "href": "./identities/jR5BRdjpG/failed-service-requests"
          },
          "posture-data": {
            "href": "./identities/jR5BRdjpG/posture-data"
          },
          "self": {
            "href": "./identities/jR5BRdjpG"
          },
          "service-configs": {
            "href": "./identities/jR5BRdjpG/service-configs"
          },
          "service-policies": {
            "href": "./identities/jR5BRdjpG/service-policies"
          },
          "services": {
            "href": "./identities/jR5BRdjpG/services"
          }
        },
        "entity": "identities",
        "id": "jR5BRdjpG",
        "name": "client-6"
      },
      "identityId": "jR5BRdjpG",
      "identityRouterCount": 9,
      "isDialAllowed": true,
      "service": {
        "_links": {
          "configs": {
            "href": "./services/1Oh311d9m0gm2vUET6cjya/configs"
          },
          "self": {
            "href": "./services/1Oh311d9m0gm2vUET6cjya"
          },
          "service-edge-router-policies": {
            "href": "./services/1Oh311d9m0gm2vUET6cjya/service-edge-router-policies"
          },
          "service-policies": {
            "href": "./services/1Oh311d9m0gm2vUET6cjya/service-policies"
          },
          "terminators": {
            "href": "./services/1Oh311d9m0gm2vUET6cjya/terminators"
          }
        },
        "entity": "services",
        "id": "1Oh311d9m0gm2vUET6cjya",
        "name": "service-6"
      },
      "serviceId": "1Oh311d9m0gm2vUET6cjya",
      "serviceRouterCount": 9
    },
    "meta": null
  }

works if I do bind-polcy part from ziti cli

createBindPolicyResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/service-policies" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "service-6-bind-policy",
    "type": "Bind",
    "semantic": "AllOf",
    "serviceRoles": ["@service-6"],
    "identityRoles": ["#router-group"]
  }' --insecure)

echo "$createBindPolicyResponse" | jq 
{
  "error": {
    "cause": {
      "field": "serviceRoles",
      "reason": "no services found with the given ids",
      "value": "[service-6]"
    },
    "code": "COULD_NOT_VALIDATE",
    "message": "The supplied request contains an invalid document or no valid accept content were available, see cause",
    "requestId": "02rKr-jpG"
  },
  "meta": {
    "apiEnrollmentVersion": "0.0.1",
    "apiVersion": "0.0.1"
  }
}

I think the issue you're facing is that there were no terminators listed in the API after you created a service, but it started working correctly?

Then, you tried to create a Bind Service Policy with an explicit mention of a service's symbolic name @service-6, and got an error. This is because the API expects the ID, not the symbolic name property of the entity when explicitly granting in a policy, e.g., @1Oh311d9m0gm2vUET6cjya.

ya as the error message suggested , I tried but it does not work . Whereas doing it in old way via cli works

If I delete that policy created by api and then just manually you this sort of command

ziti edge create service-policy "hello-bind-policy" Bind \
    --service-roles '@hello-service' --identity-roles '#hello-hosts'

everything works . API issue

You may use the unique ID or symbolic name with the CLI. When using the API you must use the unique ID, not the symbolic name.

This is how I think it works, but I wasn't able to test it today:

{
    "name": "service-6-bind-policy",
    "type": "Bind",
    "semantic": "AllOf",
    "serviceRoles": ["@1Oh311d9m0gm2vUET6cjya"],
    "identityRoles": ["#router-group"]
  }

Ohk Idk how but it works now . thanks alot . maybe the above apis were helpful docs

1 Like